更改viewmodel属性时,为什么我的视图不会更新?

时间:2016-11-29 18:04:49

标签: c# wpf mvvm data-binding inotifypropertychanged

我有一个基于DataGrid的{​​{1}}个对象视图。当用户双击一行时,我打开一个模型窗口来查看/编辑单击的约会。我通过以下命令执行此操作,绑定到Appointment鼠标事件。绑定工作正常,并且命令被正确调用。

LeftDoubleClick

所选项和命令参数_doubleClickCommand = new DelegateCommand<AppointmentRowViewModel>(async p => { if (BossViewModel.ShowModalCommand.CanExecute(null)) { var modal = new AppointmentFormWindow(); await modal.ViewModel.Populate(p.Id, Cts.Token); BossViewModel.ShowModalCommand.Execute(modal); } }, p => true ); p,是AppointmentRowViewModel对象的纯粹表示模型,仅具有属性和零逻辑。

AppointmentDtoBossViewModel的视图模型,负责管理显示哪个视图,在本例中,用于显示模态和消息框。我在此处负责,因为消息框需要一个所有者窗口,这是唯一知道其视图的视图模型。从MainWindow开始管理其他窗口也是有意义的。

因此MainWindowViewModel创建了一个它想要打开的窗口的实例,在这种情况下,该窗口的XAML会为其分配DoubleClickCommand。该命令在该视图模型上调用AppointmentFormViewModel以加载约会并将其映射到该视图模型:

Populate

我在这里使用public override async Task Populate(int? entityId = null, CancellationToken cancellation = new CancellationToken()) { if (entityId.HasValue) { await _apptService.Load(entityId.Value, this, cancellation); } IsInitialized = true; OnAllPropertiesChanged(); }

INotifyPropertyChanged

然后public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnAllPropertiesChanged() { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(string.Empty)); } 看起来像这样:

BossViewModel.ShowModalCommand

一切正常,约会从DB加载,映射到其viewmodel,已经分配给_showModalCommand = new DelegateCommand<IModal>(async modal => { modal.ViewModel.BossViewModel = this; modal.ShowDialog(); }, a => !ModalOpen ); 。模态打开,但其视图模型已完全填充,不更新表单字段以反映viewmodel属性值。好像我正在创建一个新约会。

我的所有数据绑定都使用“Mode = TwoWay ,NotifyOnSourceUpdated = True ”,所以我希望在viewmodel上设置一个值,并且提升AppointmentGridWindow会更新view元素,但是视图仍然完全空白。

UPDATE:以下是视图中的XAML摘录,而不是空白。它们绑定的viewmodel属性都具有有效值,因为该表单仅适用于捕获。

PropertyChanged

问题已解决:突然,经过大量代码检查,编辑上述代码摘录和一些Git回滚后,现在可以正确填充相关视图。我认为它正在制作绑定<Window.DataContext> <vm:AppointmentFormViewModel /> </Window.DataContext> ..... <TextBlock Text="Topic:" /> <TextBox Text="{Binding Topic, Mode=TwoWay}" /> <TextBlock Text="Venue: " /> <TextBox Text="{Binding Venue, Mode=TwoWay}" /> <TextBlock Text="Start Date: " /> <DatePicker SelectedDate="{Binding StartDate, Mode=TwoWay}" /> <ComboBox IsEditable="False" ItemsSource="{Binding TimeList}" SelectedItem="{Binding Path=StartTime, Mode=TwoWay}" /> <TextBlock Text="End Date: "/> <DatePicker SelectedDate="{Binding EndDate}" /> <ComboBox IsEditable="False" ItemsSource="{Binding Path=TimeList}" SelectedItem="{Binding Path=EndTime, Mode=TwoWay}" /> .... <DataGrid x:Name="TheList" Grid.Row="1" ItemsSource="{Binding Attendees}"....> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding GivenName}" Header="Given Name" /> <DataGridTextColumn Binding="{Binding FamilyName}" Header="Family Name" /> <DataGridTextColumn Binding="{Binding Phone}" Header="Phone" /> <DataGridTextColumn Binding="{Binding EMail}" Header="Email" /> <DataGridTextColumn Binding="{Binding Position}" Header="Position" /> <DataGridTextColumn Binding="{Binding OrgName}" Header="Org." /> <DataGridTextColumn Binding="{Binding BranchName}" Header="Branch" /> </DataGrid.Columns> ,但是当我第一次这样做时,它不起作用。还有一件事是错误的,在做所有摆弄以回答下面的评论时,我以某种方式将某些东西恢复到适当的状态。

感谢所有评论者,感谢您的建议和帮助。

1 个答案:

答案 0 :(得分:1)

在问这个问题之前我只做了所有绑定TwoWay,到那时别的东西出了问题。我回滚了,并且再次成功TwoWay,并取得了成功。

所以,答案是,当viewmodel更改时你想要更新的绑定必须是双向的,例如:

Text="{Binding Topic, Mode=TwoWay}"