WPF Datagrid selectitem = MVVM 中的 null

发布于 2024-12-10 16:29:16 字数 1000 浏览 0 评论 0原文

我正在尝试使用 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,因此我希望数据网格也取消选择该行。相反,它保持选中状态,如果我尝试单击同一行,该属性不会更新。如果我单击任何其他行,属性将按预期更改。

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

le:这是我在虚拟机中的财产:

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

提前致谢!

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:

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

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

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

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

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

思慕 2024-12-17 16:29:16

我建议检查 Visual Studio 中的输出窗口,看看是否有任何绑定失败。

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

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

Binding 中断的原因可能有很多...

  1. SelectedUser 的类型与单个 Users 的类型不同。
  2. SelectedUser 通过引用与 Users 中的任何项目都不匹配。
  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 的信息。

I recommend to check the Output Window in visual studio and see if any Binding is failing.

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

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

The reasons for this Binding to break could be many ...

  1. SelectedUser is of different type than individual Users.
  2. SelectedUser does not match by reference with any items in Users.
  3. How and where are you setting 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.MySelItem as null, the datagrid propertly deselects. Perhaps you might need to give us more input on how are you actually setting the value as null.

陈甜 2024-12-17 16:29:16

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

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

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

}

对于 ICollectionView 执行任何操作,您将需要 IsSynchronizedWithCurrentItem设置)
就像我说的,我现在无法对此进行测试。此外,属性的设置者可能不是放置它的最佳位置。也许可以在本地为 PropertyChanged 事件创建一个事件处理程序,并将该逻辑放在那里。

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

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:

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

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

}

(For ICollectionView to do anything, you will need to have IsSynchronizedWithCurrentItem set)
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.

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

悲念泪 2024-12-17 16:29:16

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

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

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

SelectedItem="{Binding SomeProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
茶花眉 2024-12-17 16:29:16

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 WPF工具包如果您的目标是 .NET 4.0,则可以修改样式

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

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

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

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

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

And dont forget to attach this style to the DataGridRowStyle in Datagrid

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文