我是WPF和C#的新手,我正在构建我的第一个应用程序,主要是使用代码示例。我确信可能有更好的方法可以做到这一点,我还没理解,所以我会向你们提出一些建议。
我有一个嵌套对象的树视图控件,它从我也构建的WCF服务下载到ObservableCollection视图模型中。我有在XAML的Windows.Resources中声明的viewmodel。
然后我的树视图通过其键名绑定到StaticResource。
Items =“{Binding Source = {StaticResource MyCatalogModel},Path = Items,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged}”
树中的数据本地保存到文件中。当viewmodel被实例化时,它会读取文件,或者如果它不存在则创建它。
我现在有2个相关问题。
有时导入的数据对象相当大,有很多嵌套对象(子对象)。这需要很长时间来更新树。我怎样才能加快速度呢?我可以“关闭”ObservableCollection的Notify更改内容,并在完成时重新加载(重新绑定?)viewmodel吗?
我想让用户能够基本清除树中的所有项目并从头开始。我有转储底层文件的代码,正如我所说,它将在实例化新的viewmodel时重新创建,但我不知道如何“重置”资源和树的绑定。我该怎么做?
感谢所有回复的人,我们将非常感谢任何代码片段!!
答案 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因渲染大型集合而变慢而闻名。抱歉,我忍不住了。