一步步学习WPF纯后台实现带checkbox的Treeview

如果在百度或者google里搜索 带checkbox的treeview,几乎能够搜索到无数的利用在treeview中利用template实现的方法,不是说这种实现方式不好,但是对于一个习惯于在后台代码中实现很多东西的我来说,来回的在不同的page中添加来添加去着实麻烦了,而且我个人还觉得有一些其他的问题。

于是开始思考如何在后台使用,而且不使用template的方法构造一个呢能够checkbox的treeview呢?

结果被我成功的实现了:显秀一个效果:

一步步学习WPF纯后台实现带checkbox的Treeview_第1张图片

经过了反复的资料查询以及反复的思想推敲,我得到如下的结论:

1、所有Template定义最终都是转化为后台代码实现,所以为什么我不能直接在后台实现呢?

2、对于一个标准的Treeview来说,其内部的每一个节点,其实是一个TreeviewItem对象;

3、Template其实就是定义一个Treeview的TreeViewItem的Header;(Header里有什么东西就显示什么东西)

4、任何一个节点的子节点,其实就是该TreeviewItem对象的Items中的另一个TreeviewItem。


所以我要做的关键就是重新定义一个符合我需要的TreeViewItem类,于是:

class CheckTreeViewItem : TreeViewItem
    {
        
    }

由于我需要的是一个带CheckBox的Treeview,于是修改代码添加内容:

class CheckTreeViewItem : TreeViewItem
    {
        private CheckBox _header = new CheckBox();
        public object Header
        {
            get
            {
                return _header.Content;
            }
            set
            {
                _header.Content = value;                
            }
        }
    }

我定义了一个CheckBox对象 和 Header属性,这样可以将父类的Header只想CheckBox,这样就会显示CheckBox了,通过这样的方式,我可以像使用普通的TreeViewItem来使用这个带CheckBox的TreeviewItem。

为了保证我的TreeViewItem会显示CheckBox,我需要将父类的Header指向该CheckBox对象:

public CheckTreeViewItem()
        {
            base.Header = _header;
        }

由于CheckBox是可以响应点击事件的,那么为了同样达到这样的效果,于是我同样在定义中添加Click事件的响应,实现代码如下:

#region Add the Click Event
        //Add a Click Event
        public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent(
            "Click",
            RoutingStrategy.Bubble, 
            typeof(RoutedEventHandler),
            typeof(CheckTreeViewItem));

        public event RoutedEventHandler Click
        {
            add { AddHandler(ClickEvent, value); }
            remove { RemoveHandler(ClickEvent, value); }
        }

        protected void RaiseAddClickEvent()
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(CheckTreeViewItem.ClickEvent);
            RaiseEvent(newEventArgs);
        }

        //objects events handle
        private void OnClickHandle(object sender, System.Windows.RoutedEventArgs e)
        {
            RaiseAddClickEvent();
        }
        #endregion
通过这段代码,我添加了一个响应事件,不过这个事件并不能真正的响应Click动作,我需要将他绑定到CheckBox的Click事件上:

public CheckTreeViewItem()
        {
            base.Header = _header;
            _header.Click += new RoutedEventHandler(OnClickHandle);
        }

到此为止,通过简单的几步,我们已经创建了一个带CheckBox的TreeViewItem,而且我可以像使用传统的TreeViewItem来使用,但是他是带CheckBox的。

而根据需要我还为这个TreeView增加了其他的事件和方法,比如Checked和Unchecked事件,比如传回所有子节点的集合,等等



写在最后的话:其实这个实现很简单,但是为什么我当初在企图构建一个带CheckBox的TreeView的时候没有找到类似的方法呢?我个人觉得有两个原因:

1、对于一个部分人来说,这个改造是非常简单的,简单到了不需要记录这种方法;

2、对于另外一部人来说,可能是网上找到的方法反正让他们实现了我需要实现的东西,至于,这个方法好不好用,有没有其他的方法,完不完美,和项目是否完全搭配,可能都没有认真的考虑过。


我个人觉得,我们在使用网上的代码甚至是解决方案的时候一定不要抱着单纯的拿来主义,而是要根据实际的情况使用,更重要的是,遇到各种问题应该努力寻求一个最优解决知道,这样才能够有效的提升自己的各种能力。


你可能感兴趣的:(实用技巧)