Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
888 views
in Technique[技术] by (71.8m points)

c# - WPF selection of a TreeView item as context menu is called

This problem relates mainly to context menus, but in my specific case it's about a TreeView control.

The TreeView item contains a StackPanel, and on that StackPanel is a ContextMenu property, which I have assigned to a StaticResource (which is a ContextMenu of course). Said ContextMenu leads to an ICommand and, thus, does its thing.

At present (and this is the default behaviour I believe), right clicking on an item in the TreeView does not select that item. This is common in Windows, but doesn't happen here. I would like it to happen (but I don't know how).

A little follow up information: I do have a selected item in the TreeView and this changes with a mouse left click. It's not a left click event, though, rather the event is 'SelectedItemChanged'. This leads to a method whereby I set the 'SelectedItem' in my data context (view model) to the SelectedItem. It has to be done this way because a TreeView's selected item is 'read only'.

That code is here, although I'm not sure how useful it is to the issue at hand:

private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        if (this.ScenesTreeView01 == null)
            return;

        if (this.ScenesTreeView01.DataContext == null)
            return;

        var DataContext = this.ScenesTreeView01.DataContext as ScenesViewModel;

        if (e.NewValue is SceneViewModel)
        {
            DataContext.SelectedScene = (SceneViewModel)e.NewValue;
        }

        if (e.NewValue is CharacterViewModel)
        {

            DataContext.SelectedCharacter = (CharacterViewModel)e.NewValue;
        }
    }

Since there doesn't seem to be a place where it says 'okay you left clicked and so here is the selected item', I don't know what to do to tell it to assign the selected item on a right click (as well as a left click).

How can I do this?

Edit: I am using MVVM so when we have a method like SelectedItemChanged with a parameter which is RoutedPropertyChangedEventArgs e, e.Source refers me back to my view model, not to a TreeViewItem.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could add an IsSelected property to your SceneViewModel and CharacterViewModel classes and bind the IsSelected of the TreeViewItem to these properties using a style. In the same style you could then hook up an event handler for the PreviewMouseRightButtonDown to set the source property:

<TreeView x:Name="treeView">
    <TreeView.Resources>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
            <EventSetter Event="PreviewMouseRightButtonDown" Handler="treeView_PreviewMouseRightButtonDown" />
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu>
                        <MenuItem>1</MenuItem>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
    </TreeView.Resources>
</TreeView>

private void treeView_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    TreeViewItem tvi = sender as TreeViewItem;
    CharacterViewModel cvm = tvi.DataContext as CharacterViewModel;
    if (cvm != null)
    {
        cvm.IsSelected = true;
    }
    else
    {
        SceneViewModel svm = tvi.DataContext as SceneViewModel;
        if (svm != null)
            svm.IsSelected = true;
    }
}

Make sure that the CharacterViewModel and SceneViewModel classes implement the INotifyPropertyChanged interface and raise the PropertyChanged event in the setter of the new IsSelected property.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...