1

TreeViewXAMLページで保持されているすべての静的アイテムを持つWPF MVVMアプリケーションを使用しています。どのMenuItemがクリックされたかをビューモデルで知るにはどうすればよいですか。これにより、それぞれのページを適切に表示できます。

    <TreeView Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="MyTreeViewMenu" 
                      VerticalAlignment="Stretch" Width="Auto" Opacity="1" 
                     BorderThickness="1" BorderBrush="Black" Grid.Row="2">

        <TreeViewItem Header="Country" Width="Auto" HorizontalAlignment="Stretch" 
                      ></TreeViewItem>

        <TreeViewItem Header="View Details" Width="Auto" HorizontalAlignment="Stretch" IsEnabled="False">
                <TreeViewItem Header="User" />
                <TreeViewItem Header="Group" />
                <TreeViewItem Header="User Group" />
            </TreeViewItem>
    </TreeView>
4

4 に答える 4

0

完全を期すために、添付プロパティと 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);
    }
}
于 2013-08-16T14:30:20.633 に答える