代码之家  ›  专栏  ›  技术社区  ›  Mark Carpenter

WPF绑定在短时间使用后会自动失败

  •  1
  • Mark Carpenter  · 技术社区  · 14 年前

    如果要编译并运行以下代码,您会发现选择和/或取消选择行会导致向输出窗口写入一行(因为对所述代码进行更仔细的检查会使人相信)。

    在使用箭头键(分别按住向上和向下箭头几次以遍历整个数据集)更改网格的选定行之后,您会震惊地(就像我一样)注意到输出消息停止,即使在网格的行中继续循环。

    我正试图达到类似于 this answer .

    我完全困惑了什么会导致网格上的绑定自动失败?非常感谢您的帮助!!另外,如果有人有时间复制这个,请评论你的发现。

    XAML:

    <Window x:Class="WpfApplication1.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window1" Height="300" Width="300">
        <Grid>
            <DataGrid Name="TheGrid">
                <DataGrid.Resources>
                    <Style TargetType="{x:Type DataGridRow}">
                        <Setter Property="IsSelected" 
                                Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
                    </Style>
                </DataGrid.Resources>
                <DataGrid.Columns>
                    <DataGridTextColumn IsReadOnly="True" 
                                        Binding="{Binding Name}" Header="Name"/>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>
    

    代码隐藏:

    using System;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows;
    
    namespace WpfApplication1 {
        public partial class Window1 : Window {
            public Window1() {
                InitializeComponent();
                TheGrid.ItemsSource = Enumerable.Range(1, 100)
                                     .Select(i => new MyClass("Item " + i));
            }
        }
    
        public class MyClass : INotifyPropertyChanged {
            public string Name { get; private set; }
    
            private bool m_IsSelected;
            public bool IsSelected {
                get {
                    return m_IsSelected;
                }
                set {
                    if (m_IsSelected != value) {
                        m_IsSelected = value;
                        Console.WriteLine(Name + ": " + m_IsSelected);
                        PropertyChanged(this, 
                            new PropertyChangedEventArgs("IsSelected"));
                    }
                }
            }
    
            public MyClass(string name) {
                Name = name;
            }
    
            public event PropertyChangedEventHandler PropertyChanged = 
                                                                delegate { };
        }
    }
    

    提前谢谢!

    编辑:

    • 尝试应用 DataGridRow 使用RowStyleSelector设置样式 属性-失败。

    • 尝试应用 数据网格行 使用样式 Row_Loading Row_Unloading 事件-失败。

    • 尝试使用自定义 MultiSelectCollectionView -失败(不适用于DataGrid控件)

    • 尝试设置 VirtualizingStackPanel.IsVirtualizing="False" -失败(成百上千行异常缓慢)

    • 试着搞乱 VirtualizingStackPanel.VirtualizationMode (标准或回收)-不合格。

    正如我在下面的一条评论中所述,最主要的问题是,我需要将DataGrid的SelectedItems属性绑定到我的ViewModel,但不能绑定,因为SelectedItems是只读的。

    必须有某种纯MVVM,开箱即用的解决方案,但到目前为止,它逃避我!

    1 回复  |  直到 8 年前
        1
  •  1
  •   Colin Thomsen    14 年前

    我刚试过,也有同样的行为。我可以通过更改DataGrid来解决问题,以防止它进行如下虚拟化: <DataGrid Name="TheGrid" AutoGenerateColumns="False" VirtualizingStackPanel.IsVirtualizing="False"> .

    有关详细信息,请参阅 MSDN forum post .