MVVM WPF DataGrid SelectedItem通过绑定触发OnPropertyChanged两次

时间:2012-06-22 09:33:28

标签: wpf binding mvvm datagrid selecteditem

我花了几个小时试图解决下面描述的问题:

我的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 );
    }

任何想法可能导致我的问题?

2 个答案:

答案 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方法的调用解决了问题。