为什么更改视图模型属性时视图没有更新?



我有一个基于DataGridAppointment对象视图。当用户双击一行时,我打开一个模型窗口以查看/编辑单击的约会。我通过下面的命令执行此操作,绑定到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,一个AppointmentDto对象的纯表示模型,只有属性和零逻辑。

BossViewModelMainWindow的视图模型,负责管理显示哪个视图,在这种情况下,负责显示模态和消息框。我把这个责任放在这里,因为消息框需要一个所有者窗口,这是唯一知道其视图的视图模型。从MainWindowViewModel打开和管理其他窗口也很有意义。

因此,DoubleClickCommand创建它想要打开的窗口的实例,在这种情况下,该窗口的 XAML 为其分配一个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看起来像这样:

_showModalCommand = new DelegateCommand<IModal>(async modal =>
{
modal.ViewModel.BossViewModel = this;
modal.ShowDialog();
},
a => !ModalOpen
);

一切正常,约会从数据库加载,映射到其视图模型,该视图模型已分配给AppointmentGridWindow。模式打开,但其视图模型已完全填充,任何表单字段都不会更新以反映视图模型属性值。就好像我在创建一个新的约会。

我所有的数据绑定都使用"Mode=TwoWay,NotifyOnSourceUpdate=True",因此我希望在视图模型上设置一个值并提出PropertyChanged将更新视图元素,但视图仍然完全空白。

更新:下面是视图中的 XAML 摘录,而不是保持空白。它们绑定到的视图模型属性都具有有效值,因为窗体仅适用于捕获。

<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>

问题已解决:突然间,经过大量代码检查、编辑上述代码摘录和一些 Git 回滚,有问题的视图现在可以正确填充。我认为它使绑定TwoWay,但是当我第一次这样做时,它不起作用。还有一点不对劲,在摆弄回答下面的评论时,我不知何故将某些东西恢复到适当的状态。

谢谢大家,评论者,提供建议和帮助。

在问这个问题之前,我只TwoWay了所有的绑定,到那时还有其他问题。我回滚,让他们再次TwoWay,成功了。

因此,答案是,当视图模型更改时,要更新的绑定必须是双向的,例如:

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

相关内容

  • 没有找到相关文章

最新更新