WPF Datagrid selecteditem = null in MVVM



我正在尝试使用MVVM模式处理数据网格。问题是,每当我将绑定到SelectedItem的VM属性更改为null时,视图不会"取消选择"当前选中的项目。这是我在xaml:

中的绑定
<DataGrid Grid.Column="0" Grid.Row="0" 
    ItemsSource="{Binding Path=Users}" 
    AutoGenerateColumns="False" 
    CanUserAddRows="False" 
    IsReadOnly="True" 
    SelectedItem="{Binding Path=SelectedUser, Mode=TwoWay}">

SelectedItem绑定从视图工作到VM,因此在SelectedUser属性中我总是有被选中的对象。问题是,在虚拟机中,我正在做一些东西,有时会改变SelectedUser属性为null,所以我希望数据网格取消选择行。相反,它仍然是选中的,如果我尝试单击同一行,属性不会更新。如果单击任何其他行,属性将按预期更改。

是否有办法使数据网格取消选择,如果它的绑定属性被设置为null?此外,我正在寻找一个MVVM解决方案,因为我不想写后面的代码。我可以通过编写代码来解决这个问题,所以不要浪费时间提供这样的解决方案:)

。:这是我在VM中的属性:

public RPLUser SelectedUser
        {
            get
            {                
                return selectedUser;
            }
            set
            {
                selectedUser = value;
                OnPropertyChanged("SelectedUser");
            }
        }

提前感谢!

我建议在visual studio中检查Output Window,看看是否有任何Binding失败。

你确定当你选择的东西,选择更新到SelectedUser属性?

你是否在SelectedUser的setter中设置了一个断点,并看到当你在数据网格上选择某些东西时它正在命中?

这个Binding破裂的原因可能有很多…

  1. SelectedUser与单个Users类型不同。
  2. SelectedUserUsers中的任何项不匹配。
  3. 如何以及在哪里设置null?

下面的代码在我的例子中工作得很好…

    <tk:DataGrid MaxHeight="200" AutoGenerateColumns="False"
                 ItemsSource="{Binding}"
                 SelectedItem="{Binding MySelItem,
                                        ElementName=MyDGSampleWindow,
                                        Mode=TwoWay}"
                 IsReadOnly="True">
        <tk:DataGrid.Columns>
            <tk:DataGridTextColumn Header="Key"
                                   Binding="{Binding Key,
                                                     Mode=OneWay}"/>
            <tk:DataGridTextColumn Header="Value"
                                   Binding="{Binding Value,
                                                     Mode=OneWay}"/>
        </tk:DataGrid.Columns>
    </tk:DataGrid>

当我将MyDGSampleWindow.MySelItem设置为null时,数据网格将正确地取消选择。也许你需要给我们更多的输入,你是如何实际设置值为null

您是否尝试在DataGrid的xaml属性中设置IsSynchronizedWithCurrentItem="True" ?这将允许您通过将SelectedUser设置为null来取消选中它。
我现在不能测试它,但你也可以试着把它添加到属性的setter中:

set
{
    selectedUser = value;
    OnPropertyChanged("SelectedUser");
    ICollectionView collectionView = CollectionViewSource.GetDefaultView(Users);
    collectionView.MoveCurrentTo(selectedUser);
}

(ICollectionView要做任何事情,你需要设置IsSynchronizedWithCurrentItem)
就像我说的,我现在不能测试这个。此外,属性的setter可能不是放置它的最佳位置。也许可以在本地为PropertyChanged事件创建一个事件处理程序,并将该逻辑放在那里。

让我知道它是否有帮助,否则我会看看我是否可以运行一个简短的测试…

可能需要添加XAML UpdateSourceTrigger来更新UI。

SelectedItem="{Binding SomeProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

DataGrid不会自动取消选择它,因为DataGridRowIsSelected属性应该设置为False

你可以通过在DataGrid上设置样式来实现。像

    <Style x:Key="dataGridRowStyle"
           BasedOn="{StaticResource {x:Type WPFToolkit:DataGridRow}}"
           TargetType="{x:Type WPFToolkit:DataGridRow}">
        <Setter Property="IsSelected" Value="{Binding Path=IsSelected}" />
    </Style>  

IsSelected属性应该是对象的属性也就是说在你的例子中RPLUser应该有一个属性Isselected

那么在您将SelectedUser设置为null之前…只做SelectedUser.IsSelected=False

不要忘记将此样式附加到Datagrid中的DataGridRowStyle

我使用的是WPFToolkit,如果你的目标是.NET 4.0,你可以修改样式

最新更新