设置属性值从一个附加属性
问题描述:
我有一个名为TreeViewSelectedItem的附加属性。为了不涉及为什么需要这个附加属性的太多细节,我会说它必须根据在TreeView中选择什么类型的项目来更新我的VM上的不同属性。设置属性值从一个附加属性
我的问题是,我似乎无法让我的代码更新VM上的属性。
XAML中设置:
<TreeView ItemsSource="{Binding Lists}" l:BindableSelectedItemBehavior.TreeViewSelectedItem="{Binding SelectedListGroup}">
<ItemsControl.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding }" >
<TextBlock Text="{Binding Key}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Key}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</ItemsControl.ItemTemplate>
</TreeView>
我的附加属性:
public static object GetTreeViewSelectedItem(DependencyObject obj)
{
return (object)obj.GetValue(TreeViewSelectedItemProperty);
}
public static void SetTreeViewSelectedItem(DependencyObject obj, object value)
{
obj.SetValue(TreeViewSelectedItemProperty, value);
}
// Using a DependencyProperty as the backing store for TreeViewSelectedItem. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TreeViewSelectedItemProperty =
DependencyProperty.RegisterAttached("TreeViewSelectedItem", typeof(object), typeof(BindableSelectedItemBehavior), new UIPropertyMetadata(null,
(s,a) =>
{
TreeView tree = s as TreeView;
if (tree == null)
return;
if (a.NewValue != null)
{
tree.SelectedItemChanged += tree_SelectedItemChanged;
tree.SourceUpdated += tree_SourceUpdated;
}
else
{
}
}));
static void tree_SourceUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
{
throw new NotImplementedException();
}
static void tree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
TreeView tree = sender as TreeView;
object binding;
BindingExpression bindingExp;
if (tree == null)
return;
bindingExp = BindingOperations.GetBindingExpression(tree, BindableSelectedItemBehavior.TreeViewSelectedItemProperty);
binding = GetTreeViewSelectedItem(tree);
if (binding == null)
return;
if (binding.GetType() == e.NewValue.GetType())
{
System.Diagnostics.Debug.WriteLine("Type match");
binding = tree.SelectedItem;
//tree.SetValue(BindableSelectedItemBehavior.TreeViewSelectedItemProperty, tree.SelectedItem);
//SetTreeViewSelectedItem(tree, tree.SelectedItem);
tree.SetCurrentValue(BindableSelectedItemBehavior.TreeViewSelectedItemProperty, tree.SelectedItem);
}
}
在底部,我已经尝试了许多不同的方式去尝试任何这种附加属性绑定到一个更新,但它似乎没有击中VM属性的Set方法(不会触及断点)。
如何更新该属性?
答
事实证明,解决方案是1:使用SetTreeViewSelectedItem(tree, tree.SelectedItem);
(我已经注释掉) 和2:在绑定中使用Mode = TwoWay。
我会注意到,另一种解决我在此尝试完成的方法是使用TreeView的IsSelected属性并将其绑定到基础VM上的某个布尔属性。许多人(如Julien和Maverik)指出了这一点。虽然我不能在我特殊的情况下使用它,但这是99.9%的情况。
只是一个友好的评论:如果你订阅一个事件不要忘了取消补充。给你提问。创建一个从Treeview派生的类并覆盖'SelectedItem'属性 – lokusking
@lokusking,可能更容易,很好的接受退订。这只是测试代码,所以我并不担心,但对于任何想要这样做的人来说,这是非常重要的,不要离开!而且你是对的,在这一点上,子类化TreeView可能会更简单。 –
有趣的是,Treeview作为这个属性,但只读。 [这](http://*.com/questions/1000040/data-binding-to-selecteditem-in-a-wpf-treeview)可能会帮助你进一步desicions – lokusking