【问题标题】:WPF Datagrid selecteditem = null in MVVMWPF Datagrid selecteditem = MVVM 中的 null
【发布时间】:2011-12-11 14:47:55
【问题描述】:

我正在尝试使用 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 属性中,我始终拥有选定的对象。问题是在 VM 中我正在做一些有时会将 SelectedUser 属性更改为 null 的东西,所以我希望数据网格也取消选择该行。相反,它仍然处于选中状态,如果我尝试单击同一行,则该属性不会更新。如果我单击任何其他行,则属性会按预期更改。

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

l.e.:这是我在 VM 中的属性:

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

提前致谢!

【问题讨论】:

  • 当您在视图模型中设置属性时,您是否调用 OnPropertyChanged 事件让视图知道它需要更新?
  • 是的,我正在编辑描述以提及这一点。好问题,谢谢!
  • 您能否发布用于在 VM 中设置属性的代码以及属性本身的代码?
  • 在绑定中设置 UpdateSourceTrigger=PropertyChanged 可能会有所帮助。
  • 我会尝试 OnPropertyChanged("");绑定可能会发生一些奇怪的事情,但看起来确实不错。您是否尝试过对集合设置断点以查看 SelectedUser 是否在您将其设置为 NULL 后的某个时间再次设置?还要确保您设置的是 SelectedUser 属性,而不是它返回的变量。

标签: wpf binding mvvm datagrid selecteditem


【解决方案1】:

我建议检查 Visual Studio 中的 Output Window 并查看是否有任何 Binding 失败。

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

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

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 的信息。

【讨论】:

  • 你是对的,我没有将属性设置为 null,因为我应该有。我正在创建一个新对象,而不是将其设置为 null。通过首先将属性设置为 null 然后给它一个新对象来解决它。谢谢!
【解决方案2】:

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

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

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

}

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

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

【讨论】:

  • 我遇到了类似的问题,设置 IsSynchronizedWithCurrentItem="True" 对我有用!!
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    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 设置为空之前...只需执行SelectedUser.IsSelected=False

    别忘了将此样式附加到 Datagrid 中的DataGridRowStyle

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

    【讨论】:

    • 你可以删除 BasedOn BasedOn="{StaticResource {x:Type WPFToolkit:DataGridRow}}"
    • 这看起来不是数据网格行没有被取消选择的问题。我刚刚检查了它,在基本设置中,当通过 Binding 将所选项目设置为 null 时,数据网格会取消选择。
    • @AngelWPF 我试图以 tat 方式做到这一点,但它不起作用,所以我尝试了 Style 方式
    猜你喜欢
    • 2012-09-30
    • 1970-01-01
    • 2012-06-19
    • 2011-11-01
    • 1970-01-01
    • 2012-06-12
    • 2012-11-30
    • 2012-06-24
    • 2017-02-20
    相关资源
    最近更新 更多