我有一個基於Appointment
對象的視圖。當用戶雙擊一行時,我打開一個模型窗口來查看/編輯點擊的約會。我通過下面的命令執行該操作,綁定到LeftDoubleClick
鼠標事件。綁定工作和命令被正確調用。當我更改viewmodel屬性時,爲什麼不更新視圖?
_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
對象純粹表現模型,只有屬性和零邏輯。
BossViewModel
是MainWindow
的視圖模型,負責管理顯示哪個視圖,在這種情況下,用於顯示模態和消息框。我將這個責任放在這裏,因爲消息框需要一個擁有者窗口,而這是唯一知道其視圖的視圖模型。它也是開放並管理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
);
一切工作正常,約會從數據庫加載,映射到它的viewmodel,它已被分配到AppointmentGridWindow
。模式打開,但其視圖模型已完全填充,表單字段中的非字段將更新以反映視圖模型屬性值。這就好像我正在創建一個新的約會。
我所有的數據綁定使用「模式=雙向
,NotifyOnSourceUpdated =真
」,所以我希望設置的視圖模型的值,提高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
,但當我第一次這樣做時,它不起作用。還有一件事是錯誤的,在回答下面的評論時做了所有的擺弄,我以某種方式恢復了某種狀態。
謝謝大家,評論者,爲您提供建議和幫助。
郵報(部分)的XAML,也期待在輸出窗口綁定錯誤。 。 –
確保您從UI線程調用您的UI通知方法。這裏有很多異步,如果不在UI線程上執行,UI更改可能會丟失。 –
此外,VS中的應用程序輸出窗口可能會顯示一些不引發異常的綁定錯誤。這可能是有用的信息。 –