【问题标题】:WPF DataGrid flickering issueWPF DataGrid 闪烁问题
【发布时间】:2018-08-04 22:07:10
【问题描述】:

在 WPF 中,我有一个 DataGrid 绑定到 ViewModel 类中的 DataView。这是一个触摸面板嵌入式项目,所以每次我在面板上触摸和滑动手指时,它都会不断向我发送值并将这些值保存到DataTable 并以它可以显示的方式将其分配给绑定DataView数据更新时只有 5 或 10 行(预定义)。每次我得到一个新行时,我都会删除最后一行,直到 DataTable 总行数为 5/10。

这里的问题是DataGrid 绑定到最后一个值需要比平时更长的时间。当我将手从面板上抬起时,我希望网格会绑定到这些值,但执行此操作需要大约 6 到 10 秒,而用户必须等待它完成。

为此,我在XAML 中使用了IsAsync 属性。正如预期的那样,这使得DataGrid 绑定速度很快,但每次数据更新时,DataGrid 都会闪烁。如何克服DataGrid 中的闪烁问题?或者有没有其他方法可以做到这一点。我们遵循 MVVM 模式进行绑定。

XAML:

<DataGrid
    ItemsSource="{Binding Path=View, IsAsync=True, UpdateSourceTrigger=PropertyChanged}"
    CanUserSortColumns="False"  
    CanUserResizeRows="False"
    HorizontalScrollBarVisibility="Hidden" 
    VerticalScrollBarVisibility="Hidden"
    EnableColumnVirtualization="True" 
    EnableRowVirtualization="True"
    CanUserAddRows="False">

</DataGrid>

查看模型:

private void InsertCollection(List<string> values)
{
    if (values == null || !values.Any()) return;

    try
    {
        var dataRow = ObjectMessageDataTable.NewRow();
        int columnCount = ObjectMessageDataTable.Columns.Count;

        var inputs = values.Select(y => y as object).ToArray();
        for (var i = 0; i < inputs.Count() && i < columnCount; i++)
            dataRow[i] = values[i];

        ObjectMessageDataTable.Rows.InsertAt(dataRow, 0);
        var count = ObjectMessageDataTable.Rows.Count;

        while (count > NumOfRows)
        {
            ObjectMessageDataTable.Rows.RemoveAt(NumOfRows);
            count = ObjectMessageDataTable.Rows.Count;
        }

        ObjectMessageDataTable.AcceptChanges();
        View = ObjectMessageDataTable.DefaultView;
    }
    catch (Exception ex)
    {

    }
}

【问题讨论】:

  • 没有任何代码,那赏金就是浪费名誉。如果您想要任何有用的答案,您应该包括minimal reproducible example。有很多方法可以做到这一点,但具体细节很大程度上取决于您当前的实现。除非你期待一个通用的答案,要求你重写所有你应该分享的东西。
  • 你现在可以看到示例代码
  • 你能分享datagrid xaml和集合绑定的完整代码吗?所以可以运行和测试。
  • 如果您使用 MVVM 模式并正确实施 iNotifyPropertyChanged,则不必添加和删除行。只需从集合中删除值即可自动更新 DataGrid。您能否发布一个在此 DataGrid 中使用的模型示例?
  • 这段代码在很多层面上看起来都很狡猾。我建议您使用 ObservableCollection> 而不是 DataView 重写它。为什么需要将values 中的项目转换为对象?

标签: wpf xaml mvvm data-binding datagrid


【解决方案1】:

我试过你的代码。直接对数据表进行数据绑定非常简单,闪烁就会消失:)。只需使用 ObjectMessageDataTable.DefaultView 而不是 View。因为每次创建 View 时都会以某种方式创建 View 对象本身,这会导致数据网格从头开始初始化。

 ItemsSource="{Binding Path=ObjectMessageDataTable.DefaultView, IsAsync=True, UpdateSourceTrigger=PropertyChanged}"

所以改成

<DataGrid
        Grid.Row="1"
        Width="Auto"
        Height="Auto"
        Margin="0,20,0,0"
        HorizontalAlignment="Center"
        VerticalAlignment="Top"
        HorizontalContentAlignment="Center"
        VerticalContentAlignment="Center"
        AlternatingRowBackground="WhiteSmoke"
        AlternationCount="2"
        AutoGenerateColumns="True"
        BorderBrush="Black"
        BorderThickness="1"
        CanUserAddRows="False"
        CanUserResizeRows="False"
        CanUserSortColumns="False"
        ColumnHeaderHeight="35"
        EnableColumnVirtualization="True"
        EnableRowVirtualization="True"
        HorizontalScrollBarVisibility="Hidden"
        ItemsSource="{Binding Path=ObjectMessageDataTable.DefaultView, IsAsync=True, UpdateSourceTrigger=PropertyChanged}"
        RowHeight="30"
        VerticalScrollBarVisibility="Hidden" />

希望对你有帮助。

【讨论】:

  • 这并没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review
  • 我正在尝试帮助另一个程序员.. 如果这是一个大错误,那么我不需要你的声誉系统!感谢您做出贡献的动力!!!!!
  • 嗨@nath,欢迎来到stackoverflow :),您在上面看到的评论是在审核答案时自动生成的,这家伙并不是故意伤害您。想一想,发布答案时的这些规则使 stackoverflow 如此出色,答案会在不同级别进行审查,以确保将来遇到相同问题的人总是会发现答案有用。
  • 嗨,Usama,感谢您的客气话。是的,我理解,我也有很好的意图,但我理解 :) 非常感谢
  • @Csharp_crack,我希望它有帮助:)
猜你喜欢
  • 2016-05-31
  • 2012-07-05
  • 2015-01-04
  • 2016-03-06
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多