2013-04-21 60 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中的一個屬性。

相關問題