2012-04-23 251 views
1
数据绑定的TreeView项目

有很多这种类型在这里SO的问题,但都回答了,所以我决定创建一个快捷新的。标题是不言自明的,所以这是问题。 TreeView控件:展开/折叠与HierarchicalDataTemplate

<TreeView> 
    <TreeView.Resources> 
     <Style TargetType="TreeViewItem"> 
      <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" /> 
      <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" /> 
      <Setter Property="FontWeight" Value="Normal" /> 
      <Style.Triggers> 
       <Trigger Property="IsSelected" Value="True"> 
        <Setter Property="FontWeight" Value="Bold" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </TreeView.Resources> 
</TreeView> 

HierarchicalDataTemplate:

var labelFactory = new FrameworkElementFactory(typeof(TextBlock)); 
var template = new HierarchicalDataTemplate(typeof(Node)) { ItemsSource = new Binding("Children") }; 
labelFactory.SetBinding(TextBlock.TextProperty, new Binding("Text")); 
template.VisualTree = labelFactory; 
treeView.ItemTemplate = template; 

我型我结合:

var hierarchy = Helpers.GetHierarchy(); 
var rootNode = new Node(); 
rootNode.Children.Add(hierarchy); 
GVSObjectStructureTreeView.ItemsSource = rootNode.Children; 
:需要适当的显示层次的

public class Node 
{ 
    public List<Node> Children { get; set; } 

    public Node Parent { get; set; } 

    public bool IsSelected { get; set; } 
    public bool IsExpanded { get; set; } 
} 

实际结合,空白根

有需要t o选择/编程展开具体项目,但是当我做

var itemToSelect = FindTreeViewItem(treeView.ItemsSource as List<Node>, elementId); 
itemToSelect.IsSelected = true; 

没有任何反应。相同的扩展。我想这个问题是有约束力的,但无法弄清楚。预先感谢您的帮助。

+0

我想你会希望使用['的ObservableCollection '](http://msdn.microsoft.com/en-us/library/ms668604.aspx)或一些其他集合执行'INotifyCollectionChanged',否则集合改变将不会被反射。当然,如果孩子是不可改变的,那不是问题。 – 2012-04-23 14:26:48

+0

更改列表到的ObservableCollection。仍然没有运气,选择不起作用。 – Jaded 2012-04-23 14:40:57

+0

我从来没有声称它会,它只是涉及收集的变化,你已经有了项目,所以你显然没有绑定后更改的集合。 – 2012-04-23 14:44:21

回答

2

重写服务类和问题得到解决。这里有两个递归层次结构帮手我实现了(可能对别人有用):

private static Node FindTreeViewItem(IEnumerable<Node> treeViewItems, string key) 
{ 
     if (treeViewItems == null) return null; 
     foreach (var item in treeViewItems) 
     { 
     if (item.AssociatedObject.ID.Equals(key)) 
     { 
      return item; 
     } 
     if (item.Children != null) 
     { 
      var childItem = FindTreeViewItem(item.Children, key); 
      if (childItem != null) 
      { 
       return childItem; 
      } 
     } 
     } 
     return null; 
} 

private static void ExpandTreeViewItemParents(Node treeViewItem) 
{ 
    if (treeViewItem == null) return; 
    if (treeViewItem.Parent != null) 
    { 
     treeViewItem.Parent.IsExpanded = true; 
    } 
    ExpandTreeViewItemParents(treeViewItem.Parent); 
} 

用于单击处理程序如下:

var selectedItem = FindTreeViewItem(treeView.ItemsSource as List<Node>, ID); 
if (selectedItem != null) 
{ 
    selectedItem.IsSelected = true; 
    ExpandTreeViewItemParents(selectedItem); 
} 
1

它看起来不像你的班级implementsINotifyPropertyChanged,所以即使绑定是正确的,也不会发生任何事情,除非为了简洁而省略。

+0

双向数据绑定是否在没有额外管道的情况下处理更新?将INPC添加到我的节点,没有任何改变。 – Jaded 2012-04-23 14:07:12

+0

@Jaded:'TwoWay'只意味着控件可以改变绑定的源属性。例如'TextBoxe.Text'默认绑定'TwoWay',所以绑定属性可以被编辑。任何[绑定错误](http://blogs.msdn.com/b/wpfsldesigner/archive/2010/06/30/debugging-data-bindings-in-a-wpf-or-silverlight-application.aspx)? – 2012-04-23 14:10:30

+0

有在具有丑陋的RelativeSource FindAncestor路径相同的应用程序窗口的工具栏组件一个绑定错误,但它不是有关这个问题,我猜,所以没有。但我同意这个问题可能在绑定语法的某个地方,尽管它看起来是正确的(hierarchytemplate绑定到根节点Children,而TreeViewItem IsSelected绑定到子节点IsSelected属性。 – Jaded 2012-04-23 14:19:18