当使用数据绑定时,我如何从TreeView中提取SelectedItem ?
本文关键字:TreeView 提取 SelectedItem 数据 绑定 定时 | 更新日期: 2023-09-27 18:10:10
我按照本文的建议将treeview控件绑定到xml文档:http://www.codeproject.com/Articles/317766/Displaying-XML-in-a-WPF-TreeView?msg=4546407 xx4546407xx
但是,现在我不知道如何访问选中的项目。
这是我的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 XPath=@Name}" Tag="{Binding XPath=@ID}" />
</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 { }
}
因为我使用这个分层数据模板和一个文本块,我不知道该怎么做。什么好主意吗?
你应该把脏东西都去掉。您可以使用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
}
}
}
在使用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的Selected Item的值为VM类的SelectedTreeItem属性,并将触发更改事件,以便您执行进一步的操作。
我还可以看到,目前您正在使用XML数据作为您的数据上下文,所以您可能需要根据您的使用情况调整上述代码,概念保持不变。如果不打算更改数据上下文,则可以在相应XAML的代码后面文件中声明附加的属性。但是我建议你做一些重构,为你的XAML实现一个VM类,并在你的新VM中将XML数据作为属性公开。