Simple Universal TreeView (WPF)

Source: Internet
Author: User

In the work to create a TreeView for many classes, many times just because to display the field is different, you have to CTRL + C, CTRL + V to copy a nearly identical code, which is inevitably annoying, so you want to like the extension of the generic collection method, you can use the flexibility to specify which field to display.

The following TreeView implements this logic: if the parent item is ticked or unchecked, all its sub-items are changed to be checked or unchecked; The parent item is automatically changed to be checked only when all the sub-items are checked.

  1. Create a basic Commontreeviewitemmodel
        <summary>///General-purpose TreeViewItem model that contains only the most basic checkbox (if you don't look good, modify the style in Commontreeview.xaml), and also contains a TAG (contained object) Business logic: The parent item is checked or unchecked, then all its sub-items are changed to be ticked or unchecked; Only when all the sub-items are checked, the parent item is automatically changed to be checked///all fields are changed to protected for easy inheritance modification//</summary> public class Commontreeviewitemmod        el:inotifypropertychanged {#region Property public event PropertyChangedEventHandler propertychanged;        protected object ID; <summary>//Unique ID///</summary> public object ID {get {return} Id        } set {id = value;}        } protected string Caption; <summary>///title///</summary> public string Caption {get {retur N caption; } set {caption = value; if (propertychanged! = null) Propertychanged.invoke (this, new PropertyChangedEventArgs ("Caption"));        }} protected bool isChecked;   <summary>     is checked///</summary> public bool IsChecked {get {return IsChecked;}                set {isChecked = value;                if (propertychanged! = null) Propertychanged.invoke (this, new PropertyChangedEventArgs ("IsChecked"));                Setischeckedbyparent (value);            if (Parent! = null) parent.setischeckedbychild (value);        }} protected bool isexpanded; <summary>//Whether or not to be expanded///</summary> public bool IsExpanded {get {R Eturn isexpanded; } set {isexpanded = value; if (propertychanged! = null) Propertychanged.invoke (this, new Propertychangedeventa RGS ("isexpanded"));        }} protected Commontreeviewitemmodel parent;            <summary>//Parent project///</summary> public Commontreeviewitemmodel Parent {            get {return parent;} set {parent =Value        }} protected List<commontreeviewitemmodel> children = new list<commontreeviewitemmodel> (); <summary>//Sub-projects included///</summary> public list<commontreeviewitemmodel> Ch            Ildren {get {return children;}        set {children = value;}        }///<summary>/////</summary> public object Tag {get; set;}        <summary>////The type of the object////</summary> public type Tagtype {get; set;}  #endregion #region The business logic, if you need to change to another logic, the two lines to be modified, or//<summary>///Sub-project ischecked change, notify whether to change isChecked//</summary>//<param name= "value" ></param> public virtual void SetI            Scheckedbychild (bool value) {if (this.ischecked = = value) {return; } bool isallchildrenchecked = this. Children.            All (c = c.ischecked = = true);            this.ischecked = isallchildrenchecked;            if (propertychanged! = null) Propertychanged.invoke (this, new PropertyChangedEventArgs ("IsChecked"));        if (Parent! = null) parent.setischeckedbychild (value); }///<summary>///ischecked changed, all sub-projects must be changed////</summary>//<param name = "value" ></param> public virtual void setischeckedbyparent (bool value) {this.ischecked            = value;            if (propertychanged! = null) Propertychanged.invoke (this, new PropertyChangedEventArgs ("IsChecked")); foreach (var. children) {Child.            Setischeckedbyparent (value); }} #endregion}
  2. Creating a generic Commontreeview, the most critical of which is the generic method Setitemssourcedata<tsource, tid>
        Public partial class Commontreeview:usercontrol {public ilist<commontreeviewitemmodel> itemssourced        ATA {get {return (ilist<commontreeviewitemmodel>) Innertree.itemssource;}        } public Commontreeview () {InitializeComponent (); }///<summary>//Set data source, and individual fields///</summary>//<typeparam name= "TSource" & gt; Data source Type </typeparam>//<typeparam name= "TId" > Primary key Type </typeparam>//<param name= "Itemsa Rray "> Data source list </param>//<param name=" Captionselector "> Specify properties shown as caption </param>//<p        Aram Name= "Idselector" > Specify primary Key Properties </param>//<param name= "Parentidselector" > Specify parent Project primary key Properties </param> public void Setitemssourcedata<tsource, tid> (ienumerable<tsource> Itemsarray, Func<tsource, string > Captionselector, Func<tsource, tid> idselector, Func<tsource, tid> Parentidselector) where tid:iequatable<tid> {var list = new List<commontreev            Iewitemmodel> (); foreach (var item in itemsarray.where (a = = object).                Equals (Default (TId), Parentidselector (a))) {var TVI = new Commontreeviewitemmodel (); TVi. Caption = Captionselector (item).                ToString (); TVi.                Id = Idselector (item); TVi.                Tag = Item; TVi. Tagtype = Item.                GetType (); List.                ADD (TVI);            Recursiveaddchildren (TVI, Itemsarray, Captionselector, Idselector, parentidselector);            } innertree.itemssource = list;        Return }///<summary>//recursive loading children///</summary>/<typeparam name= "TSource" &G t;</typeparam>//<typeparam name= "TId" ></typeparam>///<param name= "parent" ></ param>//<param name= "ItemsarrAy "></param>//<param name=" Captionselector "></param>//<param name=" Idselector " ></param>//<param name= "Parentidselector" ></param>//&LT;RETURNS&GT;&LT;/RETURNS&G        T Private Commontreeviewitemmodel Recursiveaddchildren<tsource, tid> (commontreeviewitemmodel parent, Ienumerable<tsource> Itemsarray, Func<tsource, string> captionselector, Func<TSource, TId> Idselector, Func<tsource, tid> parentidselector) {foreach (var item in itemsarray.where (A = P Arent.                Id.equals (Parentidselector (a))) {var TVI = new Commontreeviewitemmodel (); TVi.                Caption = Captionselector (item); TVi.                Id = Idselector (item); TVi.                Tag = Item; TVi. Tagtype = Item.                GetType (); TVi.                parent = parent; Parent.                Children.add (TVI); Recursiveaddchildren (TVI, Itemsarray, CAPtionselector, Idselector, parentidselector);        } return parent; }
  3. Commontreeview the corresponding XAML
    <usercontrol x:class= "Wpfcommontreeview.commontreeview" xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml /presentation "xmlns:x=" Http://schemas.microsoft.com/winfx/2006/xaml "xmlns:mc=" Http://schemas.ope              nxmlformats.org/markup-compatibility/2006 "xmlns:d=" http://schemas.microsoft.com/expression/blend/2008 " Xmlns:local= "Clr-namespace:wpfcommontreeview" mc:ignorable= "D" d:designheight= "D:des"                 ignwidth= > <Grid> <treeview name= "Innertree" > <TreeView.ItemContainerStyle> <style targettype= "TreeViewItem" > <setter property= "isexpanded" value= "{Bindin G isexpanded, Mode=twoway} "></Setter> </Style> &LT;/TREEVIEW.ITEMCONTAINERSTYLE&G            T <TreeView.ItemTemplate>  
  4. Demo Effect

Instance code download

PostScript: To say the truth, this universal TreeView is actually not universal, simple is true, the main reason is that the actual business of the TreeView hierarchy and logic is very different, just try it yourself.

Reprint Please specify source: http://www.cnblogs.com/zhouandke/p/6201064.html

Simple Universal TreeView (WPF)

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.