我是WPF和C#的新手,主要通过使用代码示例来构建我的第一个应用程序。我相信可能有一些更好的方法可以做到这一点,但我还不明白,所以我来找你们一些建议。
我有一个包含一堆嵌套对象的树视图控件,这些对象从我也构建的WCF服务下载到ObservableCollection视图模型中。我有在XAML的Windows.Resources中声明的视图模型。
然后,我的树视图通过其密钥名称绑定到该StaticResource。
Items="{Binding Source={StaticResource MyCatalogModel},Path=Items,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
树中的数据将在本地保存到一个文件中。当视图模型被实例化时,它会读取文件,或者在文件不存在的情况下创建它。
我现在有两个相关的问题。
-
有时,导入的数据对象相当大,包含许多嵌套对象(子对象)。更新树需要很长时间。我该如何加快速度?我可以"关闭"ObservableCollection的Notify更改内容,并在完成后重新加载(重新绑定?)视图模型吗?
-
我想让用户能够基本上清除树中的所有项目,并从头开始。我有一些代码可以转储底层文件,正如我所说,当实例化一个新的视图模型时,它将被重新创建,但我不知道如何"重置"资源和树的绑定。我该怎么做?
感谢所有回复的人,任何代码片段都将不胜感激!!
我也遇到了类似的问题,我在一个集合中有大量数据,而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方法并传入对象列表。这大大提高了性能。
至于重新创建树——如果它是基于视图模型的话。只是绑定到的视图模型的新版本。
令人惊讶的是,同样的老问题一次又一次地出现。是的,我不知道你为什么是Binding
对StaticResource
,但这是个坏主意。
只需在视图模型中创建一个类型为ObservableCollection<T>
的public
属性,以您喜欢或知道的任何方式将其实例设置为视图的DataContext
。请确保在代码后面正确实现INotifyPropertyChanged
接口,或者声明DependencyProperty
。然后您可以将Bind
直接连接到此属性,我们称之为Items
:
<TreeView ItemsSource="{Binding Items}" ... />
当你以这种方式设置它时,那么你所需要做的就是清空或重置TreeView
(在视图模型中):
Items = new ObservableCollection<YourItemDataType>();
至于速度,很难知道你在做什么,但WPF在渲染大型集合时速度较慢。对不起,我帮不了你。