wpf如何刷新绑定的viewmodel

时间:2013-11-21 16:15:30

标签: c# wpf xaml

我是WPF和C#的新手,我正在构建我的第一个应用程序,主要是使用代码示例。我确信可能有更好的方法可以做到这一点,我还没理解,所以我会向你们提出一些建议。

我有一个嵌套对象的树视图控件,它从我也构建的WCF服务下载到ObservableCollection视图模型中。我有在XAML的Windows.Resources中声明的viewmodel。

然后我的树视图通过其键名绑定到StaticResource。

Items =“{Binding Source = {StaticResource MyCatalogModel},Path = Items,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged}”

树中的数据本地保存到文件中。当viewmodel被实例化时,它会读取文件,或者如果它不存在则创建它。

我现在有2个相关问题。

  1. 有时导入的数据对象相当大,有很多嵌套对象(子对象)。这需要很长时间来更新树。我怎样才能加快速度呢?我可以“关闭”ObservableCollection的Notify更改内容,并在完成时重新加载(重新绑定?)viewmodel吗?

  2. 我想让用户能够基本清除树中的所有项目并从头开始。我有转储底层文件的代码,正如我所说,它将在实例化新的viewmodel时重新创建,但我不知道如何“重置”资源和树的绑定。我该怎么做?

  3. 感谢所有回复的人,我们将非常感谢任何代码片段!!

2 个答案:

答案 0 :(得分:0)

我遇到了类似的问题,我在集合中有大量数据 - 并且OnPropertyChanged的事件正在为集合中的每个项目触发。我添加了一个扩展,其中包含一个向ObservableCollection添加范围的方法。以下是扩展程序的代码。

public class SmartCollection<T> : ObservableCollection<T>
{
    public SmartCollection()
        : base()
    {
        _suspendCollectionChangeNotification = false;
    }


    bool _suspendCollectionChangeNotification;

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (!_suspendCollectionChangeNotification)
        {
            base.OnCollectionChanged(e);
        }
    }

    public void SuspendCollectionChangeNotification()
    {
        _suspendCollectionChangeNotification = true;
    }

    public void ResumeCollectionChangeNotification()
    {
        _suspendCollectionChangeNotification = false;
    }


    public void AddRange(IEnumerable<T> items)
    {
        this.SuspendCollectionChangeNotification();
        int index = base.Count;
        try
        {
            foreach (var i in items)
            {
                base.InsertItem(base.Count, i);
            }
        }
        finally
        {
            this.ResumeCollectionChangeNotification();
            var arg = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
            this.OnCollectionChanged(arg);
        }
    }

}

因此,而不是ObservableCollection,它是一个SmartCollection。我所做的是将我的对象集合构建到List中,然后调用AddRange方法并传入对象列表。这大大提高了性能。

至于重新创建树 - 如果它基于viewmodel。刚刚新建了它绑定的viewmodel。

答案 1 :(得分:0)

令人惊讶的是,有多少次同样的旧问题一次又一次地出现。是的,我不知道为什么你Binding StaticResource,但这是一个坏主意。

只需在视图模型中创建public类型的ObservableCollection<T>属性,无论您喜欢或知道哪种方式,都可以将其设置为视图的DataContext。确保在后面的代码中正确实现INotifyPropertyChanged Interface,或者declare a DependencyProperty。然后您可以Bind直接访问此媒体资源,我们称之为Items

<TreeView ItemsSource="{Binding Items}" ... />

当你以这种方式设置它时,你需要做的就是清空或重置TreeView就是这个(在视图模型中):

Items = new ObservableCollection<YourItemDataType>();

至于速度,很难知道你在做什么,但WPF因渲染大型集合而变慢而闻名。抱歉,我忍不住了。