2012-04-23 89 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