2011-09-29 34 views
1

我有这样一个类:树视图通过不同的列表复选框绑定

public class Project 
{ 
List<Object> list1; 
List<Object> list2; 
} 

我想在TreeView控件中显示此类似如下:

Checkbox + "Listing1" 
--> Checkbox + Object 1 of list1 
--> Checkbox + Object 2 of list1 
Checkbox + "Listing2" 
--> Checkbox + Object 1 of list2 
-->Checkbox + Object 2 of list2 

我最大的问题正在使2个列表之间的区别+一些额外的:如果list2不包含任何对象,则可能不会显示“Listing2”标头。

有没有人有什么好的想法我可以做到这一点?

回答

1

您可以通过扩展树型视图类像下面创建一个类TreeViewItemWithCheckbox:

public class TreeViewItemWithCheckbox : TreeViewItem 
    { 
     #region Variable Declaration 

     CheckBox chkBox = new CheckBox(); 
     StackPanel stpContent = new StackPanel(); 

     #endregion 

     #region Properties 

     public string HeaderText 
     { 
      get { return chkBox.Content.ToString(); } 
      set { chkBox.Content = value; } 
     } 

     public bool IsChecked 
     { 
      get { return chkBox.IsChecked.Value; } 
      set { chkBox.IsChecked = value; } 
     } 

     #endregion 

     #region Constructor 

     public TreeViewItemWithCheckbox() 
     { 
      stpContent.Orientation = Orientation.Horizontal; 

      chkBox = new CheckBox(); 
      chkBox.VerticalAlignment = VerticalAlignment.Center; 
      chkBox.Click += new RoutedEventHandler(SetCheckboxes); 
      chkBox.Margin = new Thickness(0, 0, 0, 0); 
      stpContent.Children.Add(chkBox); 

      Header = stpContent; 
     } 

     #endregion 

     #region Event Handlers 

     private void SetCheckboxes(object sender, RoutedEventArgs e) 
     { 
      TreeViewItemWithCheckbox selectedItem = ((TreeViewItemWithCheckbox)((StackPanel)((CheckBox)sender).Parent).Parent); 

      if (selectedItem != null) 
      { 
       /* Set checkboxes for all child items */ 
       if (selectedItem.Items.Count > 0) 
       { 
        SetChildItemCheckboxes(selectedItem, selectedItem.IsChecked); 
       } 

       /* Check if all childs checked then check/uncheck parent accoringly */ 
       if (selectedItem.Parent.GetType() == typeof(TreeViewItemWithCheckbox)) 
       { 
        TreeViewItemWithCheckbox parentItem = (TreeViewItemWithCheckbox)selectedItem.Parent; 

        bool bIsAllChecked = true; 
        foreach (TreeViewItemWithCheckbox item in parentItem.Items) 
        { 
         if (!item.IsChecked) 
         { 
          bIsAllChecked = false; 
          break; 
         } 
        } 
        parentItem.IsChecked = bIsAllChecked; 
       } 
      } 
     } 

     private void SetChildItemCheckboxes(TreeViewItemWithCheckbox item, bool IsChecked) 
     { 
      if (item.Items.Count > 0) 
      { 
       foreach (TreeViewItemWithCheckbox childItem in item.Items) 
       { 
        SetChildItemCheckboxes(childItem, IsChecked); 
        item.IsChecked = IsChecked; 
       } 
      } 
      else 
       item.IsChecked = IsChecked; 
     } 

     #endregion 
    } 

然后,你需要从2列表中添加树视图节点如下图所示:

trvTest.Items.Clear(); 

//Add default root element 
TreeViewItemWithCheckbox rootNode = new TreeViewItemWithCheckbox(); 
rootNode.HeaderText = "Root"; 
rootNode.IsExpanded = true; 
trvTest.Items.Add(rootNode); 

if (_project.list1.Count > 0) 
{ 
    TreeViewItemWithCheckbox nodeHead1 = new TreeViewItemWithCheckbox(); 
    nodeHead1.HeaderText = "Listing 1"; 
    rootNode.Items.Add(nodeHead1); 

    TreeViewItemWithCheckbox node1; 
    for (int i = 0; i < _project.list1.Count; i++) 
    { 
     node1 = new TreeViewItemWithCheckbox(); 
     node1.HeaderText = _project.list1[i].Name; 
     nodeHead1.Items.Add(node1); 
    } 
} 

if (_project.list2.Count > 0) 
{ 
    TreeViewItemWithCheckbox nodeHead2 = new TreeViewItemWithCheckbox(); 
    nodeHead2.HeaderText = "Listing 2"; 
    rootNode.Items.Add(nodeHead2); 

    TreeViewItemWithCheckbox node2 = new TreeViewItemWithCheckbox(); 
    for (int i = 0; i < _project.list2.Count; i++) 
    { 
     node2 = new TreeViewItemWithCheckbox(); 
     node2.HeaderText = _project.list2[i].Name; 
     nodeHead2.Items.Add(node2); 
    } 
} 
+0

我已经试过这个解决方案,但是我不能得到复选框... – user970714

+0

您面临复选框的问题是什么?我已经更新了我的答案,并在treeview中为复选框添加了一个更多链接。该链接中有最后一个例子。 –

+0

它不显示任何复选框。我尝试过使用HierarchicalDataTemplate,但由于某种原因,这似乎没有应用 – user970714

1

这可以解决没有TreeView - 只有2 CheckBoxes和2 ItemsControl与具体的ItemTemplate。

我更喜欢解决这个问题是这样的:

  <StackPanel> 
       <StackPanel.Resources> 
        <DataTemplate x:Key="MyTemplate"> 
         <StackPanel Orientation="Horizontal"> 
          <CheckBox Content="{Binding SomeProperty}" IsChecked="{Binding SomeBooleanProperty}" /> 
         </StackPanel> 
        </DataTemplate> 
       </StackPanel.Resources> 
       <CheckBox Content="List number 1" /> 
       <ItemsControl ItemsSource="{Binding list1}" ItemTemplate="{StaticResource MyTemplate}" /> 
       <CheckBox Content="List number 2" /> 
       <ItemsControl ItemsSource="{Binding list2}" ItemTemplate="{StaticResource MyTemplate}" /> 
      </StackPanel> 

至于你额外:可以绑定可见性的财产在你Project类,这将是看起来像:

public class Project 
{ 
     public List<Object> list1; 
     public List<Object> list2; 
     public Visibility Visuality 
     { 
      get 
      {     
       return this.list2.Any() ? Visibility.Visible : Visibility.Colapsed; 
      } 
     } 
} 

,比代码:

<ItemsControl Visibility="{Binding Visuality}" ... /> 
<CheckBox Visibility="{Binding Visuality}" ... /> 

...如果我理解你的权利......

1

如果你的第一个“清单”的项目是静态的,你可以做这样的事情

<TreeView x:Name="tv"> 
    <TreeViewItem Header="Listing 1" ItemsSource="{Binding list1}"/> 
    <TreeViewItem Header="Listing 2" ItemsSource="{Binding list2}"/> 
</TreeView> 

要隐藏没有孩子的元素,您需要一些代码。

var view = CollectionViewSource.GetDefaultView(_project.list1); 
view.Filter = myFilter; 
view.Refresh(); 

tv.DataContext = _project; 

对于课程的两份名单。