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

Why isn't my view updating when I change viewmodel properties?

我对 Appointment 个对象有一个基于 DataGrid 的视图。当用户双击一行时,我打开一个模型 window 到 view/edit 单击的约会。我通过下面的命令执行此操作,绑定到 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 是一个 AppointmentRowViewModelAppointmentDto 对象的纯表示模型,仅具有属性和零逻辑。

BossViewModelMainWindow 的视图模型,负责管理显示哪个视图,在本例中,用于显示模式和消息框。我把这个责任放在这里是因为消息框需要一个所有者 window,这是唯一知道它的视图的视图模型。从 MainWindowViewModel.

打开和管理其他 windows 才有意义

所以 DoubleClickCommand 创建了一个它想要打开的 window 的实例,并且 XAML 为那个 window,在这种情况下,分配了一个 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, NotifyOnSourceUpdated=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}"