WPF TreeView递归异步绑定

原贴地址:http://blog.csdn.net/qing2005/article/details/6523002

using System;   
using System.Collections.Generic;   
using System.Linq;   
using System.Text;   
using System.ComponentModel;   
using System.Collections.ObjectModel;   
  
namespace DepartmentTreeView {   
    public class DepartmentViewModel:INotifyPropertyChanged {   
        //临时子节点用,当Expanded时移除此节点,添加子节点   
        static readonly DepartmentViewModel _temp = new DepartmentViewModel(null);   
        //选中的子节点   
        private static ObservableCollection<DepartmentViewModel> _checkedItems = new ObservableCollection<DepartmentViewModel>();   
        //根节点   
        static DepartmentViewModel _rootItem;  
 
        #region fields&properties   
        private bool? _isChecked;   
        public bool? IsChecked {   
            get { return _isChecked; }   
            set {   
                SetCheckState(value, true, true);   
                   
            }   
        }   
        private void SetCheckState(bool? value, bool updateChildren, bool updateParent) {   
            if (_isChecked != value) {   
                _isChecked = value;   
  
                //通知选中项的集合   
                if (_isChecked == true) {   
                    _checkedItems.Add(this);   
                    PropertyChanged(this, new PropertyChangedEventArgs("CheckedItems"));   
                } else if (_isChecked == false) {   
                    _checkedItems.Remove(this);   
                    PropertyChanged(this, new PropertyChangedEventArgs("CheckedItems"));   
                }   
  
                PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));   
  
                if (updateChildren) {   
                    if (HasChildren()) {   
                        Children.ForEach(c => c.SetCheckState(value, true, false));   
                    }   
                }   
                if (updateParent && _parent != null) {   
                    _parent.VerifyState();   
                }   
            }   
        }   
        private void VerifyState() {   
            bool? state = null;   
            for (int i = 0; i < this.Children.Count; ++i) {   
                bool? currentState = this.Children[i].IsChecked;   
                if (i == 0) {   
                    state = currentState;   
                } else if (state != currentState) {   
                    state = null;   
                    break;   
                }   
            }   
            this.SetCheckState(state, false, true);   
        }   
  
        private bool _isExpanded;   
        public bool IsExpanded {   
            get { return _isExpanded; }   
            set {   
                if (value != _isExpanded) {   
                    _isExpanded = value;   
                    PropertyChanged(this, new PropertyChangedEventArgs("IsExpanded"));   
                }   
                if (!HasChildren()) {   
                    Children.Remove(_temp);   
                    LoadChildren();   
                }   
            }   
        }   
  
        private object _current;   
        public object Current {   
            get { return _current; }   
            set { _current = value; }   
        }   
        public string DisplayText {   
            get { return ((DepartmentTreeView.DB.SampleDataSet.DepartmentRow)Current)["DName"].ToString(); }   
        }   
  
        private DepartmentViewModel _parent;   
        public DepartmentViewModel Parent {   
            get { return _parent; }   
            set { _parent = value; }   
        }   
  
        private List<DepartmentViewModel> _children;   
        public List<DepartmentViewModel> Children {   
            get { return _children; }   
            private set { _children = value; }   
        }   
        #endregion   
  
        public static List<DepartmentViewModel> Create() {   
            var list = DepartmentHelper.GetSubDepartments(0);   
            DepartmentViewModel root = new DepartmentViewModel(null);   
            _rootItem = root;   
            root.Children.Clear();   
            foreach (var item in list) {   
                root.Children.Add(new DepartmentViewModel(item));   
            }   
            return root.Children;   
        }   
        private DepartmentViewModel(object currentObject) {   
            Current = currentObject;   
            _isChecked = false;   
            Children = new List<DepartmentViewModel>();   
            Children.Add(_temp);   
        }   
  
        /// <summary>   
        /// 初始化,用于设置父节点   
        /// </summary>   
        private void Init() {   
            if (!HasChildren()) return;   
            foreach (DepartmentViewModel child in Children) {   
                child.Parent = this;   
                child.Init();   
            }   
            PropertyChanged(this, new PropertyChangedEventArgs("Children"));   
        }   
  
        /// <summary>   
        /// 加载子节点   
        /// </summary>   
        private void LoadChildren() {   
            if (Current != null) {   
                int pid = Convert.ToInt32(((DepartmentTreeView.DB.SampleDataSet.DepartmentRow)Current)["DID"]);   
                var list = DepartmentHelper.GetSubDepartments(pid);   
                foreach (var item in list) {   
                    DepartmentViewModel model = new DepartmentViewModel(item) { _isChecked = this.IsChecked };   
                    if (model.IsChecked == true) {   
                        _checkedItems.Add(model);   
                        PropertyChanged(this, new PropertyChangedEventArgs("CheckedItems"));   
                    }   
                    Children.Add(model);   
                }   
                Init();   
            }   
        }   
  
        /// <summary>   
        /// 判断是否有子节点(逻辑是:如果只有一个临时子节点,说明没有真正的子节点)   
        /// </summary>   
        /// <returns></returns>   
        private bool HasChildren() {   
            return !(Children.Count == 1 && Children[0] == _temp);   
        }   
  
        public ObservableCollection<DepartmentViewModel> CheckedItems {   
            get {   
                return _checkedItems;   
            }   
        }   
  
        public event PropertyChangedEventHandler PropertyChanged;   
    }   
}


using System.Collections.Generic;   
using System.Text;   
using System.Windows;   
using System.Windows.Data;   
using System.Windows.Documents;   
using System.ComponentModel;   
  
namespace DepartmentTreeView {   
    /// <summary>   
    /// MainWindow.xaml 的交互逻辑   
    /// </summary>   
    public partial class MainWindow : Window {   
        public MainWindow() {   
            InitializeComponent();   
        }   
  
        private void Button_Click(object sender, RoutedEventArgs e) {   
            ObjectDataProvider provider = FindResource("depProvider") as ObjectDataProvider;   
            List<DepartmentViewModel> firstLevelItems = provider.Data as List<DepartmentViewModel>;   
  
            ICollectionView view = CollectionViewSource.GetDefaultView(firstLevelItems);   
            DepartmentViewModel rootItem = view.CurrentItem as DepartmentViewModel;   
  
            List<DepartmentViewModel> checkedItems = CollectionViewSource.GetDefaultView(provider) as List<DepartmentViewModel>;   
  
            StringBuilder builder = new StringBuilder();   
            foreach (DepartmentViewModel checkItem in rootItem.CheckedItems) {   
                builder.AppendLine(checkItem.DisplayText);   
            }   
            MessageBox.Show("Checked items:/n" + builder.ToString());   
        }   
    }   
}


<Window x:Class="DepartmentTreeView.MainWindow"  
        xmlns=""  
        xmlns:x=""  
        xmlns:local="clr-namespace:DepartmentTreeView"  
        Title="MainWindow" Height="329" Width="212" FontFamily="Arial">  
    <Window.Resources>  
        <ObjectDataProvider x:Key="depProvider" ObjectType="{x:Type local:DepartmentViewModel}" MethodName="Create" />  
        <Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}">  
            <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded,Mode=TwoWay}" />  
        </Style>  
        <HierarchicalDataTemplate x:Key="CheckBoxItemTemplate" ItemsSource="{Binding Children}">  
            <StackPanel Orientation="Horizontal" Margin="0,2,0,0">  
                <CheckBox Focusable="False" IsChecked="{Binding IsChecked,Mode=TwoWay}" VerticalAlignment="Center" />  
                <ContentPresenter Content="{Binding DisplayText,Mode=OneWay}" Margin="2,0" />  
            </StackPanel>  
        </HierarchicalDataTemplate>  
    </Window.Resources>  
    <Grid Margin="5">  
        <Grid.RowDefinitions>  
            <RowDefinition />  
            <RowDefinition Height="Auto" />  
            <RowDefinition Height="Auto" />  
        </Grid.RowDefinitions>  
        <TreeView Name="tvDepartment" Grid.Row="0" ItemContainerStyle="{StaticResource TreeViewItemStyle}" ItemsSource="{Binding Source={StaticResource depProvider}}" ItemTemplate="{StaticResource CheckBoxItemTemplate}" />  
        <TextBlock Name="tbText" Margin="5" Grid.Row="1">当前选中项:<TextBlock Text="{Binding Source={StaticResource depProvider},Path=CheckedItems.Count,Mode=OneWay,IsAsync=True}" /></TextBlock>  
        <Button Margin="5" Grid.Row="2" Content="Get CheckedItems" Click="Button_Click" />  
    </Grid>  
</Window> 








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值