2016-11-29 167 views
-1

我有一個基於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對象純粹表現模型,只有屬性和零邏輯。

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

一切工作正常,約會從數據庫加載,映射到它的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,但當我第一次這樣做時,它不起作用。還有一件事是錯誤的,在回答下面的評論時做了所有的擺弄,我以某種方式恢復了某種狀態。

謝謝大家,評論者,爲您提供建議和幫助。

+4

郵報(部分)的XAML,也期待在輸出窗口綁定錯誤。 。 –

+3

確保您從UI線程調用您的UI通知方法。這裏有很多異步,如果不在UI線程上執行,UI更改可能會丟失。 –

+1

此外,VS中的應用程序輸出窗口可能會顯示一些不引發異常的綁定錯誤。這可能是有用的信息。 –

回答

0

在問這個問題之前,我只做了所有綁定TwoWay,到那時還有其他的錯誤。我回滾了,並且再次成功地將它們全部變成TwoWay

因此,答案是,當視圖模型的變化必須是雙向的,例如,你想更新綁定:

Text="{Binding Topic, Mode=TwoWay}" 
相關問題