TreeView —WPF—MVVM—HierarchicalDataTemplate详解编程语言

摘要:采用HierarchicalDataTemplate数据模板和treeview在MVVM模式下实现行政区划树,

支持勾选。勾选父节点,子节点回全部自动勾选;子节点部分勾选时,父节点半勾选;子节点全部勾选时,父节点勾选。反之亦然。

HierarchicalDataTemplate是分层数据模板,通常用于tree,menu等层级控件。

HierarchicalDataTemplate的ItemsSource属性绑定下一级数据源。
Model为行政区数据实体类,通常访问数据库获取数据并构建对象。
ViewModel为界面的抽象模型,表示界面的数据和行为,是Model和View的桥梁。

view就是界面。

TreeView —WPF—MVVM—HierarchicalDataTemplate详解编程语言

一、代码

1、Model

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
 
namespace WpfHierarchicalTemplate 
{ 
    public class District 
    { 
        public int ID { get; set; } 
        public string   Xzqhdm { get; set; }//行政区划代码 
        public string Xzqhmc { get; set; }//行政区划名称 
        public int Level { get; set; }//级别,0全国,1省,2地市,3县,4,乡镇,5,村 
        public IList<District> Children { get; set; } 
        public District Parent { get; set; } 
    } 
} 

  2、ViewModel

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Collections.ObjectModel; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
namespace WpfHierarchicalTemplate 
{ 
    public class DistrictNodeViewModel : ModelCommon.NotifyObject 
    { 
        private bool? isSelected = false; 
 
        public bool? IsSelected 
        { 
            get { return isSelected; } 
            set 
            { 
                isSelected = value; 
                RaisePropertyChanged("IsSelected"); 
            } 
        } 
 
        private bool? isChecked = false; 
 
        public bool? IsChecked 
        { 
            get { return isChecked; } 
            set 
            { 
                SetIsChecked(value); 
            } 
        } 
 
        private void SetIsChecked(bool? value) 
        { 
            if (value != isChecked) 
            { 
                isChecked = value; 
                RaisePropertyChanged("IsChecked"); 
            } 
            if (this.Children.Count > 0 && this.Children[0].isChecked != value) 
            { 
                //设置子节点勾选状态 
                foreach (var item in this.Children) 
                { 
                    if (value!=null) 
                    { 
                        item.IsChecked = value; 
                    }                     
                } 
            } 
            if (this.parent != null) 
            { 
                if (this.Parent.Children.Count == this.Parent.Children.Count(item => item.isChecked == value)) 
                { 
                    //同一级节点全部选中,则父节点选中。反之亦然。 
                    this.Parent.IsChecked = value; 
                } 
                else if (this.Parent.Children.Count > this.Parent.Children.Count(item => item.isChecked == value)) 
                { 
                    if (this.Parent.IsChecked!=null) 
                    { 
                        this.Parent.IsChecked = null; 
                    }                     
                }                 
            } 
 
        } 
 
        private bool? isExpand = false; 
 
        public bool? IsExpand 
        { 
            get { return isExpand; } 
            set 
            { 
                isExpand = value; 
                RaisePropertyChanged("IsExpand"); 
            } 
        } 
 
        private BitmapImage img; 
 
        public BitmapImage Img 
        { 
            get { return img; } 
            set 
            { 
                img = value; 
                RaisePropertyChanged("Img"); 
            } 
        } 
 
        private ObservableCollection<DistrictNodeViewModel> children = new ObservableCollection<DistrictNodeViewModel>(); 
 
        public ObservableCollection<DistrictNodeViewModel> Children 
        { 
            get { return children; } 
            set 
            { 
                children = value; 
                RaisePropertyChanged("Children"); 
            } 
        } 
 
        private DistrictNodeViewModel parent; 
 
        public DistrictNodeViewModel Parent 
        { 
            get { return parent; } 
            set 
            { 
                parent = value; 
                RaisePropertyChanged("Parent"); 
            } 
        } 
 
        private District district; 
 
        public District District 
        { 
            get { return district; } 
            set 
            { 
                district = value; 
                RaisePropertyChanged("District"); 
            } 
        } 
    } 
}

 

 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Collections.ObjectModel; 
namespace WpfHierarchicalTemplate 
{ 
    public class DistrictMainViewModel : ModelCommon.NotifyObject 
    { 
        private ObservableCollection<DistrictNodeViewModel> vmNodes; 
 
        public ObservableCollection<DistrictNodeViewModel> VmNodes 
        { 
            get { return vmNodes; } 
            set 
            { 
                vmNodes = value; 
                RaisePropertyChanged("VmNodes"); 
            } 
        } 
 
        public DistrictMainViewModel() 
        { 
            this.VmNodes = new ObservableCollection<DistrictNodeViewModel> 
            { 
                LoadData() 
            }; 
        } 
        public DistrictNodeViewModel LoadData() 
        { 
            ObservableCollection<District> rootNodes =new ObservableCollection<District>(); 
            District d00 = new District() 
            { 
                Xzqhmc = "全国", 
                Parent = null 
            }; 
            District d0 = new District() 
            { 
                 Xzqhmc="河南", 
                   Parent=d00                   
            }; 
 
            District d1 = new District() 
            { 
                Xzqhmc = "北京", 
                Parent = d00 
            }; 
 
            District d2 = new District() 
            { 
                Xzqhmc = "山东", 
                Parent = d00 
            }; 
            District d11 = new District() 
            { 
                Xzqhmc = "海淀区", 
                Parent = d1 
            }; 
            District d12 = new District() 
            { 
                Xzqhmc = "石景山区", 
                Parent = d1 
            }; 
            District d13 = new District() 
            { 
                Xzqhmc = "朝阳区", 
                Parent = d1 
            };             
 
            District d01 = new District() 
            { 
                Xzqhmc = "商丘", 
                Parent = d0 
            }; 
            District d02 = new District() 
            { 
                Xzqhmc = "郑州", 
                Parent = d0 
            }; 
            District d03 = new District() 
            { 
                Xzqhmc = "周口", 
                Parent = d0 
            }; 
            d1.Children = new List<District> { d11, d12, d13 }; 
            d0.Children = new List<District> { d01, d02, d03 }; 
            d00.Children = new List<District>{d1,d2,d0}; 
            rootNodes.Add(d00); 
            DistrictNodeViewModel dnv = new DistrictNodeViewModel(); 
            dnv.District = rootNodes[0]; 
            SetDNV(dnv, rootNodes[0]); 
            return dnv; 
        } 
 
        private void SetDNV(DistrictNodeViewModel vm,District root) 
        { 
            if (root==null||root.Children==null||root.Children.Count==0) 
            { 
                return; 
            } 
            foreach (var item in root.Children) 
            { 
                DistrictNodeViewModel vmNew = new DistrictNodeViewModel(); 
                vmNew.District = item; 
                vmNew.Parent = vm; 
                vmNew.Img = new System.Windows.Media.Imaging.BitmapImage(new Uri("/dog.jpg", UriKind.Relative)); 
                vm.Children.Add(vmNew); 
                SetDNV(vmNew, item); 
            } 
        } 
 
    } 
}

 

  3、主窗口

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
 
namespace WpfHierarchicalTemplate 
{ 
    /// <summary> 
    /// MainWindow.xaml 的交互逻辑 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
        public MainWindow() 
        { 
            InitializeComponent(); 
            this.DataContext = new DistrictMainViewModel(); 
        } 
    } 
} 

  

4、前台xaml

<Window x:Class="WpfHierarchicalTemplate.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
        <HierarchicalDataTemplate x:Key="treeTemplate" ItemsSource="{Binding Children}"> 
            <StackPanel Orientation="Horizontal"> 
                <CheckBox IsChecked="{Binding IsChecked}"></CheckBox> 
                <Image Source="{Binding Img}" Height="20" Width="16"></Image> 
                <TextBlock Text="{Binding District.Xzqhmc}"></TextBlock> 
            </StackPanel> 
        </HierarchicalDataTemplate> 
    </Window.Resources> 
    <Grid> 
        <TreeView  ItemTemplate="{StaticResource treeTemplate}" ItemsSource="{Binding VmNodes}"> 
        </TreeView> 
    </Grid> 
</Window>

 

  二、效果

TreeView —WPF—MVVM—HierarchicalDataTemplate详解编程语言

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/13172.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论