1. 程式人生 > >WPF TreeView自定義資料模板展開到指定層

WPF TreeView自定義資料模板展開到指定層

           TreeView 全部展開還是挺方便的只需設定TreeViewItem 樣式即可全部展開,但展開到具體某一級就需要手工程式碼實現。如果TreeView 沒有自定義資料模板 節點繼承TreeViewItem 那麼樹的展開可以參考 MSDN部落格  點選開啟連結

public static class ExtensionMethods
{
  public static void ExpandAll(this System.Windows.Controls.TreeView treeView)
  {
   ExpandInternal(treeView);
   }                                                                                                                                 
private static void ExpandInternal(ItemsControl targetItemContainer)
{
  if (targetItemContainer == null) return;
  if (targetItemContainer.Items == null) return;
  for (int i = 0; i < targetItemContainer.Items.Count; i++)
  {
    TreeViewItem treeItem = targetItemContainer.Items[i] as TreeViewItem;
    if (treeItem == null) continue;
   if (!treeItem.HasItems) continue;
    treeItem.IsExpanded = true;
    ExpandInternal(treeItem);
  }
 }
} 


一、設定樣式全部展開

 <UserControl.Resources>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="True" /> <!-- 設定IsExpanded 為True 即全部展開-->
        </Style>
    </UserControl.Resources>
        <DockPanel LastChildFill="True">
        <TreeView x:Name="treeView1" x:FieldModifier="private"  BorderBrush="{x:Null}">
          
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:CompanyNodeItem}" ItemsSource="{Binding Children}" >
                    <TextBlock VerticalAlignment="Center" Text="{Binding CompanyName}"  TextWrapping="Wrap" MaxWidth="200" />      </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </DockPanel>


二、利用繫結機制實現展開到具體某一級

<TreeView x:Name="treeView1" x:FieldModifier="private"  BorderBrush="{x:Null}">
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="IsExpanded" Value="{Binding Expand}" />
                    <!--是否展開繫結Expand 屬性  後臺程式碼設定Expand true false 即可展開到某一級-->
                </Style>
            </TreeView.ItemContainerStyle>
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:CompanyNodeItem}" ItemsSource="{Binding Children}" >
                    <TextBlock VerticalAlignment="Center" Text="{Binding CompanyName}" TextWrapping="Wrap" MaxWidth="200" />       </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

 節點物件

  public class CompanyNodeItem
    {
        public int CompanyId { set; get; }
        public string CompanyName { set; get; }
        public int ParentId { set; get; }
        public List<CompanyNodeItem> Children { set; get; }
        public bool Expand { set; get; }
        public CompanyNodeItem()
        {

            Children = new List<CompanyNodeItem>();
        }
    }
        /// <summary>
        /// 展開樹節點到某一級 遞迴演算法                                                                                                      /// <param name="list">構建樹的所有節點集合</param>
        /// <param name="lev"></param>
        private void ExpandInternal(List<CompanyNodeItem> list, int lev)
        {
            if (lev > 3)  //展開到第三層
                return;
            list.ForEach(s => ExpandInternal(s.Children, lev + 1));          
            list.ForEach(s=>s.Expand=true);
        }


完整後臺程式碼包括樹的建立:

  public partial class WPFCompanyTree : UserControl
    {

        private List<CompanyNodeItem> listNode;
        /// <summary>
        /// WPFCompanyTree 選擇的列改變引發的事件
        /// </summary>
        public event Action<object, CompanyNodeItem> WPFCompanyTreeSelectedItemChanged;
        private List<CompanyNodeItem> listExpandNode;
        public WPFCompanyTree()
        {
            InitializeComponent();

            this.treeView1.SelectedItemChanged += treeView1_SelectedItemChanged;
            InitDbData();
            listExpandNode = InitTreeData();
            treeView1.ItemsSource = listExpandNode;
            ExpandInternal(listExpandNode, 1);
        }

        void treeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (WPFCompanyTreeSelectedItemChanged != null)
                WPFCompanyTreeSelectedItemChanged(sender, treeView1.SelectedItem as CompanyNodeItem);
        }

        private void InitDbData()
        {
            DataTable dt = SqlClass.GetTable(@"SELECT [CID]
                  ,[CName]     
                  ,[CParentID]        
              FROM [jq.666gps.com].[dbo].[XFJCompany]");
            int count = dt.Rows.Count;
            listNode = new List<CompanyNodeItem>();
            for (int i = 0; i < count; i++)
            {
                listNode.Add(new CompanyNodeItem() { CompanyId = Convert.ToInt32(dt.Rows[i][0]),                                            CompanyName = dt.Rows[i][1].ToString(), ParentId = Convert.ToInt32(dt.Rows[i][2]) });
            }
        }
        private List<CompanyNodeItem> InitTreeData()
        {
            List<CompanyNodeItem> nodes = new List<CompanyNodeItem>();
            listNode.ForEach(s =>
            {
                if (s.ParentId == 0)
                {

                    nodes.Add(s);
                }
                else
                {
                    CompanyNodeItem temp = NextFindNode(listNode, s.ParentId);
                    if (temp != null)
                    {

                        temp.Children.Add(s);
                    }
                }
            });
            return nodes;
        }

        private CompanyNodeItem NextFindNode(List<CompanyNodeItem> list, int id)
        {
            if (list == null)
                return null;
            foreach (CompanyNodeItem node in list)
            {
                if (node.CompanyId == id)
                    return node;
                CompanyNodeItem temp = NextFindNode(node.Children, id);
                if (temp != null)
                    return temp;
            }
            return null;
        }

        /// <summary>
        /// 展開樹節點到某一級
        /// </summary>
        /// <param name="list">構建樹的所有節點集合</param>
        /// <param name="lev"></param>
        private void ExpandInternal(List<CompanyNodeItem> list, int lev)
        {
            if (lev > 3)  //展開到第三層
                return;
            list.ForEach(s => ExpandInternal(s.Children, lev + 1));          
            list.ForEach(s=>s.Expand=true);
        }


    }