2013-06-27 92 views
3

我遇到以下我不明白的行爲。我的數據正確顯示在TreeView如下。TreeView不存儲預期狀態

 
Sport 
    > BaseBall 
    > Apparel 
    > Equiptment 
     Glove 
     Bat 
    > Football 
    > Helmet 
    > Soccer 

但是,當我點擊任何節點時,底層節點數據就是它的第一個子節點。

 
    Node Clicked   Actual Data 
------------------------------------------- 
    Sport      Baseball 
    Baseball     Apparel 
    Football     Helmet 
    Bat       null 

我看了很多網絡和書籍的例子,但是我找不到這個問題;我相信這很簡單。

編輯我已目視檢查,實際上顯示類型和在TreeView每個控制的值在C#2010在調試器的每個節點,以及從馬修麥克唐納的Pro WPF使用一個方便的小代碼段。

編輯我已經用實際的完整應用程序替換了初始代碼,該應用程序再現了問題。這是我能想到的最簡單的例子。

代碼(不相關的部分移除):

<Application x:Class="WpfApplication1.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:this="clr-namespace:WpfApplication1" 
      StartupUri="MainWindow.xaml"> 
    <Application.Resources> 
     <this:MainWindowViewModel x:Key="ViewModel:MainWindow"></this:MainWindowViewModel> 
    </Application.Resources> 
</Application> 

-

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:this="clr-namespace:WpfApplication1" 
     Title="MainWindow" Height="350" Width="525" 
     DataContext="{StaticResource ViewModel:MainWindow}"> 
    <TreeView x:Name="theTree" ItemsSource="{Binding Path=OrgChart}" 
       MouseUp="theTree_MouseUp"> 
     <TreeView.Resources> 
      <HierarchicalDataTemplate ItemsSource="{Binding Path=Subordinates}" DataType="{x:Type this:OrgChartNodeViewModel}"> 
       <TextBlock Text="{Binding Path=Position.Title}"></TextBlock> 
      </HierarchicalDataTemplate> 
     </TreeView.Resources> 
    </TreeView> 
</Window> 

-

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void theTree_MouseUp(object sender, MouseButtonEventArgs e) 
    { 
     Stack<DependencyObject> stack = new Stack<DependencyObject>(); 
     var it = e.OriginalSource as DependencyObject; 
     while (it != null) 
     { 
      it = VisualTreeHelper.GetParent(it); 
      stack.Push(it); 
     } 

     int level = 0; 
     while (stack.Any()) 
     { 
      Debug.Write("".PadLeft(level++)); 
      it = stack.Pop(); 
      if (it is TreeViewItem) 
      { 
       var item = it as TreeViewItem; 
       OrgChartNodeViewModel vm = ((OrgChartNodeViewModel)((TreeViewItem)it).Items.CurrentItem); 
       if (vm != null) 
        Debug.WriteLine(vm.Position.Title); 
      } 
      else 
      { 
       Debug.WriteLine(it); 
      } 
     } 
    } 
} 

-

public class MainWindowViewModel 
{ 
    public List<OrgChartNodeViewModel> OrgChart { get; set; } 

    public MainWindowViewModel() 
    { 
     Position ceo = new Position { Title = "CEO" }; 
     Position vp = new Position { Title = "VP" }; 
     Position boss = new Position { Title = "Boss" }; 
     Position worker = new Position { Title = "Worker" }; 

     OrgChartNodeViewModel root; 
     OrgChartNodeViewModel node = new OrgChartNodeViewModel { Position = ceo }; 
     OrgChartNodeViewModel child = new OrgChartNodeViewModel { Position = vp }; 
     root = node; 
     node.Subordinates.Add(child); 
     node = child; 
     child = new OrgChartNodeViewModel { Position = boss }; 
     node.Subordinates.Add(child); 
     node = child; 
     child = new OrgChartNodeViewModel { Position = worker }; 
     node.Subordinates.Add(child); 

     OrgChart = new List<OrgChartNodeViewModel> { root }; 
    } 
} 

-

public class OrgChartNodeViewModel 
{ 
    public Position Position { get; set; } 
    public List<OrgChartNodeViewModel> Subordinates { get; set; } 

    public OrgChartNodeViewModel() 
    { 
     Subordinates = new List<OrgChartNodeViewModel>(); 
    } 
} 

-

public class Position 
{ 
    public string Title { get; set; } 
} 

這裏是我的機器上輸出...

enter image description here

+0

您如何驗證實際數據與點擊樹節點不同? – Andy

+0

我目測檢查了調試器中的每個節點,以及在C#2010中使用Mathew MacDonald's Pro WPF中的一個小代碼片段,它實際顯示了TreeView中每個控件的類型和值。 –

+1

如果你所顯示的xaml是完整的,問題是你沒有在'TreeView'上設置'HierarchicalDataTemplate',你正在將模板添加到'TreeView.Items'集合中。我很驚訝它不會拋出關於你設置'ItemsSource'和手動添加項目的例外。相反,模板應該位於UserControl的'Resources'中。 –

回答

3

嘗試切換

OrgChartNodeViewModel vm = ((OrgChartNodeViewModel)((TreeViewItem)it).Items.CurrentItem); 

OrgChartNodeViewModel vm = ((OrgChartNodeViewModel)viewItem.DataContext); 

在while循環,你想要的TreeViewItem.DataContext而不是Items.CurrentItem指向它的孩子(也是唯一一個一直存在,直到首先展開)。因此你爲什麼要看VP而不是CEO。

我全功能prolly轉出到這樣的:

private void theTree_MouseUp(object sender, MouseButtonEventArgs e) { 
    var clickedItem = e.OriginalSource as FrameworkElement; 
    if (clickedItem == null) 
    return; 
    var chartNode = clickedItem.DataContext as OrgChartNodeViewModel; 
    if (chartNode != null) 
    Debug.WriteLine(chartNode.Position.Title); 
} 

不是通過視覺樹遍歷得到TreeViewItemDataContext在您的xaml設置中被繼承,所以不妨使用它來節省冗餘工作。

+0

Crud。我知道這一定很簡單。我假設(通常是一個壞主意)DataContext屬性會返回該樹綁定的DataContext,所以我從來沒有檢查過它。謝謝您的幫助! –