我花了几个小时试图解决下面描述的问题:
我的MVVM WPF应用程序中定义了一个DataGrid,剥离的XAML代码如下所示:
<DataGrid AutoGenerateColumns="False" Name="dgdSomeDataGrid" SelectedItem="{Binding SelectedSomeItem, Mode=TwoWay}" ItemsSource="{Binding SomeItemCollection}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Id}" Header="ID" />
<DataGridTextColumn Header="Titel" Binding="{Binding Path=Title}" />
<DataGridTextColumn Header="Status" Binding="{Binding Path=State}" />
</DataGrid.Columns>
</DataGrid>
在我关联的ViewModel中,我有一个相应的属性,如:
public WorkItemForUi SelectedSomeItem
{
get
{
return SomeObject.SelectedSomeItem;
}
set
{
SomeObject.SelectedSomeItem = value;
OnPropertyChanged( "SelectedSomeItem" );
}
}
在我的控制器中,我有以下内容:
private void MainWindowViewModelPropertyChanged( object sender, PropertyChangedEventArgs e )
{
if ( e.PropertyName == "SelectedSomeItem" )
{
UpdateSelectedSomeItem();
}
}
我通常要做的是从DataGrid
检索所选项目,从外部数据存储(在本例中为TFS)获取有关该项目的更多信息,并在TextBox中显示额外信息。
所有这些都已按预期工作,但问题是MainWindowViewModelPropertyChanged方法被调用两次,而不是一次。
可能是因为SelectedItem
属性被设置为发生两次,但我不太确定我发现的很多信息有点矛盾(有时也不是非常清楚Windows Forms或WPF是否意味着。)
我见过一些建议,其中为DataGrid
定义了SelectionChanged事件处理程序,并使用了IsSelected
属性,但据我所知,由于我的数据,这不应该是必要的结合。
更新 作为MainWindowController的一部分,有一个Initialize方法引用MainWindowViewModelPropertyChanged处理程序。
public void Initialize( string tfsProjectCollection )
{
InitializeCommands();
InitializeViewModel();
AddWeakEventListener( m_MainWindowViewModel, MainWindowViewModelPropertyChanged );
}
任何想法可能导致我的问题?
答案 0 :(得分:0)
您的SomeObject.SelectedSomeItem
二传手也会加注OnPropertyChanged( "SelectedSomeItem" );
吗? SomeObject
的类型是什么?为什么SomeObject
还需要SelectedSomeItem
属性?
请在订阅MainWindowViewModelPropertyChanged
的地方发布一些代码。
我从未遇到过selecteditem
行为的问题,但为了公平起见,我不需要订阅INotifyPropertyChanged
来获取此信息。而且我认为你也不需要那样。在viewmodels之间有更好的通信方式
编辑:这有效,但我不知道你的代码中有什么SomeObject。
private WorkItemForUi _selected;
public WorkItemForUi SelectedSomeItem
{
get
{
return this._selectedSomeItem;
}
set
{
this._selectedSomeItem = value;
OnPropertyChanged( "SelectedSomeItem" );
}
}
答案 1 :(得分:0)
好的,在花了一些时间之后,我们发现问题发生在ApplicationController
类。
构造函数在该类中调用Initialize
方法,同一类中的Run
方法也称为此方法。
在Initialize
方法中,调用了主窗口的视图模型`Initialize'方法,其中添加了一个事件监听器:
[...]
AddWeakEventListener( m_MainWindowViewModel, MainWindowViewModelPropertyChanged );
[...]
从Initialize
类的构造函数中删除对ApplicationController
方法的调用解决了问题。