【问题标题】:Devexpress GridControl - refresh data in MVVMDevexpress GridControl - 在 MVVM 中刷新数据
【发布时间】:2016-03-03 15:38:49
【问题描述】:

我的网格:

<dxg:GridControl x:Name="StatisticsGridLevel1"
                 dx:ThemeManager.ThemeName="Office2013"
                 DataContext="{Binding FooViewModel}"
                 ItemsSource="{Binding FooCollection}">

视图模型:

private List<FooDto> fooCollection = new List<FooDto>();
public List<FooDto> FooCollection
{
    get
    {
        return this.fooCollection;
    }

    private set
    {
        this.fooCollection = value;
        this.NotifyPropertyChanged();
    }
}

以及示例方法:

private void Foo()
{
    foreach (var element in collection)
    {
        this.fooCollection.Add(new FooDto()
        {
            X = element.Foo1,
            Y = element.Foo2,
            Z = element.Foo3
        });
    }
    this.NotifyPropertyChanged("FooCollection");
}

当我使用 ObservableCollection 时,一切正常。但我想使用列表(不是在循环中通知)。

在网格上开始滚动后视图刷新。有什么问题?

【问题讨论】:

  • 你为什么不能坚持ObservableCollection?除非集合实现INotifyCollectionChanged,否则在修改集合时网格不会自动更新。 ObservableCollection 实现了 List 没有的接口。
  • 因为我向集合中添加了很多项目。我想在完成循环后刷新网格(手动调用 Notify)。
  • 好的,我明白了,但我不太明白你的问题。这是什么意思:'视图在网格上的启动滚轮后刷新'?什么是启动滚轮?你指的是鼠标滚轮吗?您是否正在处理鼠标滚轮事件。如果是这样,那么这听起来可能与问题有关,您应该显示代码。听起来您在说Foo 中的视图仍然令人耳目一新,尽管您使用的是List 而不是ObservableCollection?对吗?
  • No :) 在第一步中 - 我使用默认值创建 List FooCollection。这些值在网格中正确显示。在第二步中 - 我调用 Update() 方法。更新清洁集合并添加新项目。 FooCollection.Clear(); FooCollection.Add(...) // 元素 1 ... FooCollection.Add(...) // 元素 50000 this.NotifyPropertyChanged("FooCollection");网格显示旧值。我单击网格中的滚动条(使用旧值)或单击列(排序) - 网格已经显示正确的数据。

标签: c# wpf mvvm devexpress gridcontrol


【解决方案1】:

我认为CollectionViewSource 会适用于您的情况。有很多方法可以在 XAML 中、在 ViewModel 中、在 View 的代码隐藏中创建一个。为了演示目的,我将把最简单的一个放在一起,即在您的 ViewModel 上创建一个 CollectionViewSource 属性。我认为有些人可能不一定喜欢这种方法——它有点混合关注点的感觉。不过,我不确定我是否同意。如果您认为CollectionViewSource 是集合视图的对象模型,那么我认为将它放在您的 ViewModel 中没有任何问题。但我认为因为它继承自DependencyObject,所以它被污名化为更多的观点问题。无论如何,这样的事情会做你想要的:

// Assuming this is your constructor
public ViewModel()
{
    this.FooViewSource.Source = this.fooCollection;
}

private readonly List<FooDto> fooCollection = new List<FooDto>();

private readonly CollectionViewSource fooViewSource;
public CollectionViewSource FooViewSource
{
    get { return this.fooViewSource; }
}

private void Foo()
{
    foreach (var element in collection)
    {
        this.fooCollection.Add(new FooDto()
        {
            X = element.Foo1,
            Y = element.Foo2,
            Z = element.Foo3
        });
    }
    this.FooViewSource.View.Refresh();
}

然后您将您的ItemsSource 属性绑定到您的ViewModel 的FooViewSource 属性。 CollectionViewSource 对于其他事情也很方便。它支持排序、过滤、选择的项目,也许还有一些我忘记的东西。

【讨论】:

  • 您的解决方案解决了性能问题。但是 DevExpress 会阻止排序(单击鼠标右键时的排序选项是灰色的)。如果不是这个问题,这将是完美的解决方案。
  • AllowSorting 上是否有可以设置为 true 的 AllowSorting 属性?请参阅此链接底部附近的“排序和分组”:documentation.devexpress.com/#WPF/CustomDocument11124
  • 或者,如果上述方法不起作用。我会在网格控件上寻找某种默认视图。我想会有一个,它很可能具有刷新视图的功能。如果是这种情况,我会在 ViewModel 中添加一个名为 CollectionChanged 的事件,并在我更改基础列表时从 Foo 函数中调用它。然后我会让视图订阅事件并在事件触发时调用网格视图的刷新方法。
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 2019-04-14
  • 2016-06-15
  • 2015-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多