爲了完整起見,這裏的附加屬性和TreeView子選項:
附加屬性選項
public static class TreeViewSelectedItemHelper
{
public static readonly DependencyProperty BindableSelectedItemProperty
= DependencyProperty.RegisterAttached(
"BindableSelectedItem",
typeof (object),
typeof (TreeViewSelectedItemHelper),
new FrameworkPropertyMetadata(false,
OnSelectedItemPropertyChanged)
{
BindsTwoWayByDefault = true
});
public static object GetBindableSelectedItem(TreeView treeView)
{
return treeView.GetValue(BindableSelectedItemProperty);
}
public static void SetBindableSelectedItem(
TreeView treeView,
object selectedItem)
{
treeView.SetValue(BindableSelectedItemProperty, selectedItem);
}
private static void OnSelectedItemPropertyChanged(
DependencyObject sender,
DependencyPropertyChangedEventArgs args)
{
var treeView = sender as TreeView;
if (treeView == null) return;
SetBindableSelectedItem(treeView, args.NewValue);
treeView.SelectedItemChanged -= HandleSelectedItemChanged;
treeView.SelectedItemChanged += HandleSelectedItemChanged;
if (args.OldValue != args.NewValue)
SetSelected(treeView, args.NewValue);
}
private static void SetSelected(ItemsControl treeViewItem,
object itemToSelect)
{
foreach (var item in treeViewItem.Items)
{
var generator = treeViewItem.ItemContainerGenerator;
var child = (TreeViewItem) generator.ContainerFromItem(item);
if (child == null) continue;
child.IsSelected = (item == itemToSelect);
if (child.HasItems) SetSelected(child, itemToSelect);
}
}
private static void HandleSelectedItemChanged(
object sender,
RoutedPropertyChangedEventArgs<object> args)
{
if (args.NewValue is TreeViewItem) return;
var treeView = sender as TreeView;
if (treeView == null) return;
var binding = BindingOperations.GetBindingExpression(treeView,
BindableSelectedItemProperty);
if (binding == null) return;
var propertyName = binding.ParentBinding.Path.Path;
var property = binding.DataItem.GetType().GetProperty(propertyName);
if (property != null)
property.SetValue(binding.DataItem, treeView.SelectedItem, null);
}
}
子類選項
public class BindableTreeView : TreeView
{
public BindableTreeView()
{
SelectedItemChanged += HandleSelectedItemChanged;
}
public static readonly DependencyProperty BindableSelectedItemProperty =
DependencyProperty.Register(
"BindableSelectedItem",
typeof (object),
typeof (BindableTreeView),
new FrameworkPropertyMetadata(
default(object),
OnBindableSelectedItemChanged) {BindsTwoWayByDefault = true});
public object BindableSelectedItem
{
get { return GetValue(BindableSelectedItemProperty); }
set { SetValue(BindableSelectedItemProperty, value); }
}
private static void OnBindableSelectedItemChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var treeView = d as TreeView;
if (treeView != null) SetSelected(treeView, e.NewValue);
}
private static void SetSelected(ItemsControl treeViewItem,
object itemToSelect)
{
foreach (var item in treeViewItem.Items)
{
var generator = treeViewItem.ItemContainerGenerator;
var child = (TreeViewItem) generator.ContainerFromItem(item);
if (child == null) continue;
child.IsSelected = (item == itemToSelect);
if (child.HasItems) SetSelected(child, itemToSelect);
}
}
private void HandleSelectedItemChanged(
object sender,
RoutedPropertyChangedEventArgs<object> e)
{
SetValue(BindableSelectedItemProperty, SelectedItem);
}
}
'TreeViewItem.Selected'是事件不是嗎?你如何使用'StaticResource'來匹配'Command'和一個事件?此外,該請求是針對MVVM解決方案的。 – Sheridan
@Sheridan是的..答覆已更新。 –
在我的視圖模型中添加了命令和屬性。雖然命令正在菜單項選擇上被調用,但如何獲取selectedmenuItem?見下面的評論。 – user2519971