在开发过程中,项目使用了 Treeview 控件。在之前的实现过程中,控件树的源数据为
List<T>
类型,绑定在属性 ItemSource 上。若想实时更新
List
上的属性变化,需在类型T的定义过程中实现
INotifyPropertyChanged
接口,并在需要通知属性值变更的对应属性内实现类似
RaisePropertyChanged()
的方法。且在原来的开发中,没有实现对
List
内成员数量变化的时候的实时通知。
原实现方法:
Treeview.ItemSource = null;
Treeview.ItemSource = TreeviewNodes;
通过对控件绑定的源数据的“手动”更新去更新前台UI,不方便也很不科学
我们先看看 List 的定义:
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>
{...}
可以看出, List 本身是没有继承类似 Notify 的接口的,因此本身也无法提供属性改变的通知行为。
经过查找资料后,发现 .Net 提供了这样的一个集合类型 ObservableCollection<T>
public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged
{...}
该类继承了继承了Collection, INotifyCollectionChanged, INotifyPropertyChanged,其中:
所以再ObservableCollection这个类的方法,对数据的操作很少,重点放在了当自己本事变化的时候(不管是属性,还是集合)会调用发出通知的事件。
下面贴出修改后的 Treeview 控件的实现代码
后台 ViewModel 中的代码:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using sdm.Model;
namespace sdm.ViewModel
public class MainViewModel : ViewModelBase
private ObservableCollection<NodeViewModel> treeviewNodes;
public ObservableCollection<NodeViewModel> TreeviewNodes
get => treeviewNodes;
set => Set(ref treeviewNodes, value);
public MainViewModel()
TreeviewNodes = new ObservableCollection<NodeViewModel>();
for (int i = 0; i < 5; i++)
RtuModel rtu = new RtuModel();
rtu.RtuNum = i;
rtu.Address = $"测试节点{i}";
NodeViewModel node = new NodeViewModel()
Rtu = rtu,
TreeviewNodes.Add(node);
前台 xaml 中的代码:
<TreeView Grid.Row="1" x:Name="treeview" Margin="10,5,10,0" ItemsSource="{Binding TreeviewNodes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vmmain:NodeViewModel}" ItemsSource="{Binding}">
<StackPanel x:Name="SPanel" Orientation="Horizontal" Margin="0,2,0,2">
<Image Height="15" Width="15" Source="{Binding ConIcon.Source, Mode=TwoWay}"/>
<TextBlock x:Name="NodeText" Text="{Binding Title, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView>
运行后效果:
实时新增节点:
完美实现需求
[1] WPF MVVM-TreeView数据源添加了节点,UI没有刷新
[2] C# ObservableCollection和List的区别
[3] WPF中使用MVVM模式实现可动态检索的Treeview
比如要在test1234节点下新建子节点,首先要选中test1234节点,添加成功后,根据test1234结点的TID去后台请求对应子节点数据,实现动态刷新。删除节点类似。
三、代码实现
1、初始化时必须设置配置
本文样例通过NuGet获取MvvmLight框架,实现了TreeView的加载,节点添加和节点删除功能,其中节点加载的方式与常见的迭代方式不同,这里使用了字典的方式,提供了一种生成树结构数据对象的方式,如果有遇到TreeView数据加载卡顿的同学,可以考虑尝试使用这种方式。
本文主要代码如下(源码可见文章最后),
首先定义了树节点接口,包含组成树结构数据的基本属性
public inter...
<TreeView ItemsSource="{Binding Path=Model.Clusters}"
ItemTemplate="{StaticResource ClusterTemplate}"
SelectedItem="{Binding Path=Mod
TreeView控件可在树结构中显示分层数据,其中的项可以展开和折叠。它可以包含多种类型的控件,如Button、Lable、Image等控件,可以通过绑定到数据源并使用HieratchicalDataTemplate对象来填充其树。可以修改默认ControlTemplate以使控件具有独特的外观。
这里举一个完整的TreeView实例来进行说明。本节主要实现自定义控件样式+数据源绑定+动态添加父...
最近开发redis可视化ui,连到了阿里云上的redis,这个redis的hash动辄好几百条数据,拿到后写到QTableview中。测试良好。
但测试一段时间后,点了几十条hash,拿到了几十条hash数据,QTableview也更新了几十次,在进行其他操作的时候,出现了程序崩溃。
于是就想,是不是发生了内存泄漏。
假设有一个QTableview,名叫table
先看下面的代码,功能是清空TableView
void clearTreeView(){
ui->view->setM
你多观察一下,会发现有一个短暂的白屏。
一、启动白屏优化
首先我们处理白屏的问题,首先我想的是更改一下启动页的样式,之前是一片白,现在我改成绿色的,绿才有安全感,要想代码过得去,样式就得带点绿,手动滑稽。
那么首先在colors.xml中增加一个颜色值:
<color name="green">#2E
MVVM Light 是一个开源的 MVVM (Model-View-ViewModel) 框架,用于开发 Windows 平台的应用程序。它的主要优点在于简洁易用、轻量级,支持 WPF、Silverlight、Windows Phone、Windows 8/8.1、Windows 10 UWP 等平台。
下面是一个简单的 MVVM Light 使用教程:
1. 首先,安装 MVVM Light 框架。可以通过 NuGet 包管理器安装,命令如下:
Install-Package MvvmLight
2. 在项目中添加一个 ViewModel 类。这个类会绑定到 View 上。
3. 编写 View 的 XAML 代码。在根元素上添加 DataContext 属性绑定到 ViewModel。
4. 编写 ViewModel 类中的逻辑代码。这些代码会更新 View 的状态。
5. 在 View 的 XAML 代码中添加绑定。例如,将一个文本框的 Text 属性绑定到 ViewModel 中的一个属性上。
6. 在 ViewModel 中使用命令来处理 View 上的用户交互。
7. 按照需要使用其他 MVVM Light 的功能,例如消息传递、导航、本地化等。
最后,我需要提醒你 MVVM 是一种模式,不同的框架可能有不同的实现,每种框架都有它的优缺点,需要根据自己的需求来选择合适的框架.