WPF Datagrid selecteditem = MVVM 中的 null

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7833425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:08:44  来源:igfitidea点击:

WPF Datagrid selecteditem = null in MVVM

wpfbindingmvvmdatagridselecteditem

提问by Florin Bombeanu

I'm trying to work with a datagrid using the MVVM pattern. The problem is that whenever I change the VM property which is binded to SelectedItem to null, the View doesn't "deselect" the currently selected item. This is my binding in xaml:

我正在尝试使用 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}">

The SelectedItem binding works from the view to the VM thus in the SelectedUser property I always have the selected object. The problem is that in the VM I'm doing some stuff which sometimes changes the SelectedUser property to null so I would expect the datagrid to deselect the row as well. Instead, it remains selected and if I try to click on the same row, the property doesn't update. If I click on any other row, the property changes as expected.

SelectedItem 绑定适用于从视图到 VM,因此在 SelectedUser 属性中,我始终拥有所选对象。问题是,在 VM 中,我正在做一些有时会将 SelectedUser 属性更改为 null 的事情,因此我希望数据网格也取消选择该行。相反,它保持选中状态,如果我尝试单击同一行,则该属性不会更新。如果我单击任何其他行,属性会按预期更改。

Is there a way to make the datagrid deselect if it's binded property is set to null? Also I'm looking for a MVVM solution as I don't want to write code behind. I can solve this by writing code behind so don't waste time offering such solutions :)

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

l.e.: this is my property in the VM:

le:这是我在 VM 中的财产:

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

Thanks in advance!

提前致谢!

回答by WPF-it

I recommend to check the Output Windowin visual studio and see if any Bindingis failing.

我建议检查Output Window视觉工作室,看看是否有任何Binding失败。

Are you sure when you select something, the selection updates into the SelectedUserproperty?

您确定当您选择某些内容时,选择会更新到SelectedUser属性中吗?

Did u put a breakpoint in setter of SelectedUserand see that it is hitting when you select something on the datagrid?

SelectedUser当您在数据网格上选择某些内容时,您是否在 setter of 中放置了一个断点并看到它正在击中?

The reasons for this Bindingto break could be many ...

造成这种Binding破坏的原因可能有很多......

  1. SelectedUseris of different type than individual Users.
  2. SelectedUserdoes not match by reference with any items in Users.
  3. How and where are you setting null?
  1. SelectedUser是与个体不同的类型Users
  2. SelectedUser不通过引用与 中的任何项目匹配Users
  3. 您如何以及在哪里设置 null?

The following code in my case works perfectly fine...

下面的代码在我的情况下工作得很好......

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

When I set MyDGSampleWindow.MySelItemas null, the datagrid propertly deselects. Perhaps you might need to give us more input on how are you actually setting the value as null.

当我设置MyDGSampleWindow.MySelItem为 null 时,数据网格会自动取消选择。也许您可能需要为我们提供更多关于您如何实际将值设置为 null 的输入。

回答by RoelF

Did you try setting IsSynchronizedWithCurrentItem="True"in the xaml properties for the DataGrid? AFAIK, this will allow you to unselect it by setting the SelectedUser to null.
I cannot test it at the moment, but you could also try to add this in the setter of your property:

您是否尝试IsSynchronizedWithCurrentItem="True"在 DataGrid 的 xaml 属性中进行设置?AFAIK,这将允许您通过将 SelectedUser 设置为 null 来取消选择它。
我目前无法对其进行测试,但您也可以尝试将其添加到您的财产的 setter 中:

set
{
    selectedUser = value;
    OnPropertyChanged("SelectedUser");

    ICollectionView collectionView = CollectionViewSource.GetDefaultView(Users);
    collectionView.MoveCurrentTo(selectedUser);

}

(For ICollectionViewto do anything, you will need to have IsSynchronizedWithCurrentItemset)
Like I said, I cannot test this right now. Also, the setter of the property is probably not the best place to put it. Maybe create an event handler for the PropertyChangedevent locally and put that logic there.

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

Let me know if it helps, else I'll see if I can run a short test...

如果有帮助,请告诉我,否则我会看看是否可以进行简短的测试...

回答by MtEdenCodeLab

Yeah may need to add the XAML UpdateSourceTrigger to update the UI.

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

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

回答by Ankesh

The DataGrid will not Deselect it automatically as DataGridRow's IsSelectedproperty should be set to False.

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

You can do that by Setting a style on DataGrid.. like

您可以通过在 DataGrid 上设置样式来做到这一点。

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

The IsSelectedproperty should be the of the object i.e in your case RPLUsershould have a property Isselected

IsSelected属性应该是对象的,即在您的情况下RPLUser应该有一个属性 Isselected

Then before you set the SelectedUserto null... just do SelectedUser.IsSelected=False

然后在您将其设置SelectedUser为空之前...就这样做SelectedUser.IsSelected=False

And dont forget to attach this style to the DataGridRowStylein Datagrid

并且不要忘记将此样式附加到DataGridRowStyleDatagrid 中

I am using WPFToolkit you can modify the style if you are targetting .NET 4.0

我正在使用 WPFToolkit 你可以修改样式,如果你是针对 .NET 4.0