wpf企業應用之帶選項框的TreeView

  wpf裏面實現層次綁定主要使用HierarchicalDataTemplate,這裏主要談一談帶checkbox的treeview,具體效果見 wpf企業級開發中的幾種常見業務場景html

  先來看一下個人控件綁定,我這裏實現的是模塊權限的編輯。具體效果就是選中一個節點,後代節點、祖代節點狀態都會發生相應變化,具體變化邏輯你們都懂的,描述起來很羅嗦。this

<TreeView Name="TreeView_Right" ItemsSource="{Binding ModuleRight}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate DataType="{x:Type localModel:ModuleRight}" ItemsSource="{Binding ModuleChildren}">
                <CheckBox IsThreeState="{Binding IsThreeState}" Content="{Binding MenuName}" IsChecked="{Binding IsChecked}" IsEnabled="{Binding IsEnabled}"/>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
        <TreeView.ItemContainerStyle>
            <Style TargetType="TreeViewItem"  BasedOn="{StaticResource TreeViewItemStyle}">
                <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=OneWay}"/>
            </Style>
        </TreeView.ItemContainerStyle>
</TreeView>

  下面是對應的綁定類,僅供參考。這裏須要說明的就是,IsChecked每次變化時都要遞歸去修改父節點、子節點的IsChecked屬性,其餘的跟普通的treeview綁定沒什麼區別,讀者如有不明之處可自行去MSDN上查看treeview的使用。spa

public class ModuleRight : NotifyModelBase
{
   private ModuleRight _parent;
   public ModuleRight Parent
   {
      get
      {
         return _parent;
      }
      set
      {
         _parent = value;
         OnPropertyChanged("Parent");
      }
   }

   private string _menuName;
   public string MenuName
   {
       get
       {
          if (AppSetting.GetValue("language") == "en_us")
             return MenuName_EN;
          return _menuName;
       }
       set
       {
          _menuName = value;
       }
    }
    public string MenuName_EN
    {
       get;
       set;
    }

    public string ClassName
    {
       get;
       set;
    }
    private List<ModuleRight> _moduleChildren;
    public List<ModuleRight> ModuleChildren
    {
        get
        {
           return _moduleChildren ?? (_moduleChildren = new List<ModuleRight>());
        }
        set
        {
           _moduleChildren = value;
        }
    }
    private int _rightValue;
    public int RightValue
    {
        get
        {
           return _rightValue;
        }
        set
        {
           _rightValue = value;
        }
     }

     private bool _isThreeState;
     public bool IsThreeState
     {
         get
         {
           return _isThreeState;
         }
         set
         {
           _isThreeState = value;
           OnPropertyChanged("IsThreeState");
         }
     }
     private bool _isEnabled = true;
     public bool IsEnabled
     {
         get
         {
            return _isEnabled;
         }
         set
         {
            _isEnabled = value;
            OnPropertyChanged("IsEnabled");
         }
      }

      private bool? _isChecked = false;
      public bool? IsChecked
      {
         get
         {
           return _isChecked;
         }
         set
         {
           SetIsChecked(value, true, true);
         }
      }

      public bool IsExpanded
      {
         get
         {
           return _isChecked != false;
         }
      }

      public void SetIsChecked(bool? value, bool updateChildren, bool updateParent)
      {
         _isChecked = value;
         if (updateChildren && _isChecked.HasValue)//設置後代節點的選中狀態
         {
            ModuleChildren.ForEach(c => c.SetIsChecked(_isChecked, true, false));
         }
         if (updateParent && Parent != null && Parent.IsThreeState)//設置祖代節點的選中狀態
         {
            Parent.VerifyCheckState();
         }
         OnPropertyChanged("IsChecked");
      }

      public void VerifyCheckState()
      {
         bool? state = true;
         for (int i = 0; i < ModuleChildren.Count; i++)
         {
            bool? current = ModuleChildren[i].IsChecked;
            if (current == null)
            {
               state = null;
               break;
            }
            else
            {
               if (i < ModuleChildren.Count - 1 && ModuleChildren[i].IsChecked != ModuleChildren[i + 1].IsChecked)
               {
                  state = null;
                  break;
               }
            }
         }
         if (state != null)
            state = ModuleChildren[0].IsChecked;
         SetIsChecked(state, false, true);
      }

      public ModuleRight()
      {
      }
      public ModuleRight(string menuName, string menuName_en, string className)
      {
        this.MenuName = menuName;
        this.MenuName_EN = menuName_en;
        this.ClassName = className;
      }

 }
相關文章
相關標籤/搜索