2013-04-21 95 views
0

我按照这篇文章的意见在一个TreeView控件绑定到XML文档: http://www.codeproject.com/Articles/317766/Displaying-XML-in-a-WPF-TreeView?msg=4546407#xx4546407xx如何在使用数据绑定时从TreeView中提取SelectedItem?

不过,现在我无法弄清楚如何获得所选择的项目。

这是我的XAML:

<Window.Resources> 
    <XmlDataProvider x:Key="xmldata" Source="cats.xml" XPath="/CategoryArray" /> 
    <HierarchicalDataTemplate DataType="Category" ItemsSource="{Binding XPath=./*}"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Margin="5,0,0,0" Text="{Binding [email protected]}" Tag="{Binding [email protected]}" /> 
     </StackPanel> 
    </HierarchicalDataTemplate> 
    <HierarchicalDataTemplate DataType="CategoryArray" ItemsSource="{Binding XPath=./*}"> 
     <TextBlock Margin="0" Text="eBay Categories" /> 
    </HierarchicalDataTemplate> 
</Window.Resources> 
<Grid DataContext="{StaticResource xmldata}"> 
    <TreeView Name="treeView1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding}" VirtualizingStackPanel.IsVirtualizing="False" VirtualizingStackPanel.VirtualizationMode="Standard" SelectedItemChanged="treeView1_SelectedItemChanged" /> 
</Grid> 

这似乎并没有工作,我以为它会的方式:

private void treeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) 
    { 
     try 
     { 
      TreeViewItem selectedItem = treeView1.SelectedValue as TreeViewItem; 
      categoryName = selectedItem.Name; 
      categoryID = selectedItem.Tag.ToString(); 
      categoryChosen = true; 
     } 
     catch { } 
    } 

由于我使用这种分层数据模板和文字块,我不知道该怎么做。有任何想法吗?提前致谢。

+0

我在这里问了同样的问题:http://stackoverflow.com/a/9143193/279516。我最终没有使用答案,因为它很复杂。我欺骗并使用了代码隐藏文件。希望这可以帮助。 – 2013-04-21 21:22:04

+0

你是如何使用代码隐藏文件的?你的意思是你以编程方式填充树视图而不是使用绑定? – Doug 2013-04-21 21:29:18

+0

“这看起来不像我认为的那样工作。”你可以再详细一点吗?它的表现如何? – 2013-04-21 21:36:35

回答

0

你应该摆脱肮脏的尝试赶上所有。你可以使用e.NewValue并检查它是否是你指定的类型之一。既然你直接告诉WPF什么是您的数据模型,你可以使用它像这样:

private void treeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) 
{ 
    var category = e.NewValue as Category; 
    if(category != null) 
    { 
     //FIXME: do things if its Category 
    } 
    else 
    { 
     var categoryArray = e.NewValue as CategoryArray; 
     if(categoryArray != null) 
     { 
      //FIXME: do things if its CategoryArray 
     } 
    } 
} 
0

在使用XAML可以使用绑定来检索框架元素的属性。但是,在这种特殊情况下,TreeView的SelectedItem属性是只读的,因此您不能直接绑定它,但可以使用附加属性来实现相同。

我试图做一个样品的情况下

宣布在VM类附加属性与更改通知来执行你的逻辑

public static object GetSelectedTreeItem(DependencyObject obj) 
{ 
    return (object)obj.GetValue(SelectedTreeItemProperty); 
} 

public static void SetSelectedTreeItem(DependencyObject obj, object value) 
{ 
    obj.SetValue(SelectedTreeItemProperty, value); 
} 

// Using a DependencyProperty as the backing store for SelectedTreeItem. This enables  animation, styling, binding, etc... 
public static readonly DependencyProperty SelectedTreeItemProperty = 
    DependencyProperty.RegisterAttached("SelectedTreeItem", typeof(object), typeof(YourVMClass), new PropertyMetadata(null, OnSelectedItemChange)); 

public static void OnSelectedItemChange(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    //do your stuff here eg. 
    YourVMClass vm = d as YourVMClass; 
    dynamic selectedItem = e.NewValue; 
    vm.categoryName = selectedItem.Name; 
    vm.categoryID = selectedItem.Tag.ToString(); 
    vm.categoryChosen = true; 
} 

XAML中结合进如下

<TreeView vm:YourVMClass.SelectedTreeItem="{Binding SelectedItem,Mode=OneWay,RelativeSource={RelativeSource Self}}"> 

因此,这将设置TreeView的选定项目的值为VM类的SelectedTreeItem属性,并将触发更改事件以供您执行进一步的操作离子。

另外我可以看到,目前您使用XML数据作为您的数据上下文,因此您可能需要根据您的使用情况调整上述代码,概念保持不变。如果您不打算更改数据上下文,则可以在相应XAML的文件后面的代码中声明附加属性。但是我建议你做一些重构,为你的XAML实现一个VM类,并将XML数据公开为新VM中的一个属性。

相关问题