【问题标题】:Working with "AlternationCount" property of DataGrid in WPF在 WPF 中使用 DataGrid 的“AlternationCount”属性
【发布时间】:2014-11-30 08:24:25
【问题描述】:

DataGrid 的“AlternationCount”属性有问题。 我为行的背景设置了两种颜色,现在当我选择其中一行并移动滚动条时,每隔一行也会被选中! 我设置了 AlternationCount="2" 和 SelectionMode="Single"。

有人能解决这个问题吗?

C#代码:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        var data1 = new Test { Test1 = "TestCell1", Test2 = "TestCell2", Test3 = "TestCell3" };
        var data2 = new Test { Test1 = "TestCell1", Test2 = "TestCell2", Test3 = "TestCell3" };
        for (int i = 0; i < 10; i++)
        {
            dataGrid1.Items.Add(data1);
            dataGrid1.Items.Add(data2);
        }
    }

    public class Test
    {
        public string Test1 { get; set; }
        public string Test2 { get; set; }
        public string Test3 { get; set; }
    }

Xaml:

    <DataGrid AlternationCount="2" SelectionMode="Single"
            Name="dataGrid1" 
            RowBackground="Beige"
            AlternatingRowBackground="linen"
            DataContext="{Binding}"
            HorizontalAlignment="Left" Height="239.334" 
            Margin="39.333,37.333,0,0" 
            VerticalAlignment="Top" Width="432">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=Test1}" Header="Header1" />
            <DataGridTextColumn Binding="{Binding Path=Test2}" Header="Header2" />
            <DataGridTextColumn Binding="{Binding Path=Test3}" Header="Header3" />
        </DataGrid.Columns>
    </DataGrid>

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    看看下面的代码:

     private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                dataGrid1.Items.Add(new Test { Test1 = "TestCell1", Test2 = "TestCell2", Test3 = "TestCell3" });
                dataGrid1.Items.Add(new Test { Test1 = "TestCell1", Test2 = "TestCell2", Test3 = "TestCell3" });
            }
        }
    

    如果您在应用程序中尝试该代码,您会发现单个数据行的选择是正确的。您的代码中的问题是您一遍又一遍地分配对象的相同实例。因此,在以下行中,您将创建一个像这样的新对象:

    var data1 = new Test { Test1 = "TestCell1", Test2 = "TestCell2", Test3 = "TestCell3" };
    

    对象data1 被分配给您的dataGrid1 10 次。当您单击数据行时,gridcontrol 会使用equal 方法检查每一行。您没有在 Test 类中实现 equals,这意味着当它们的引用相等时,您的对象是相等的,因为您分配了相同的对象(因此相同的引用)10 次。

    更多信息来自msdn

    如果当前实例是引用类型,则 Equals(Object) 方法测试引用相等性,并且对 Equals(Object) 方法的调用等效于对 ReferenceEquals 方法的调用。引用相等意味着被比较的对象变量引用同一个对象。

    IEquatable 的实现: 要检查一个对象是否等于另一个对象,您可以使用 IEquatable 接口,如下所示:

    public class Test : IEquatable<Test>
    {
        public string Test1 { get; set; }
        public string Test2 { get; set; }
        public string Test3 { get; set; }
    
        public bool Equals(Test other)
        {
            if (other == null) return false;
            return Test1.Equals(other.Test1)
                && Test2.Equals(other.Test2)
                && Test3.Equals(other.Test3);
        }
    }
    

    通过覆盖 equals 方法,您将覆盖默认的均衡行为,该行为通过引用检查两个对象是否相等。

    【讨论】:

    • 在涉及滚动时也会发生 UI 虚拟化。
    • 谢谢。你的回答解决了我的问题。但只是一个问题:为什么滚动后选择了多行,而我设置了 SelectionMode="Single"?
    • 因为对象实际上是相等的,所以选择了不止一项。 SelectionModel“Single”确实通过均衡对象来搜索整个对象列表以查找您的对象。如果它找到多个相等的对象,则选择这些对象。我不知道 wpf 正在使用的内部滚动行为,也许这些项目在滚动后被重新选择。不过我不确定。
    猜你喜欢
    • 2012-04-03
    • 1970-01-01
    • 2012-07-17
    • 2010-10-14
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    相关资源
    最近更新 更多