2016-11-29 178 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}" 
相关问题