如何防止TreeViewItem选择?

时间:2013-09-02 16:37:10

标签: c# .net wpf treeview treeviewitem

我有一个具有2级层次结构的TreeView控件。 如果选择了第二级的项目并且用户点击了另一个项目,我需要询问他是否确定要移动到另一个项目。如果他的回答为“否”,我需要阻止选择另一个TreeViewItem。

我这样试试:

<TreeView.Resources>
    <Style TargetType="{x:Type TreeViewItem}">
        <EventSetter Event="PreviewKeyDown" Handler="TreeViewItem_OnKeyDown" />
    </Style>
</TreeView.Resources>


private void TreeViewItem_OnMouseDown(object sender, MouseButtonEventArgs e)
{
    var selectedTreeViewItem = sender as TreeViewItem;
    if (selectedTreeViewItem != null)
    {
        var myData = selectedTreeViewItem.Header as MyData;
        if (myData != null && selectedNode != null)
        {
            if (!selectedNode.DoYouAgreeToMoveToAnotherItem())
            {
                e.Handled = true;
            }
            else
            {
                myTreeView.Focus();
                myData.IsNodeSelected = true;
            }
        }
    }
}

以某种方式运作。但是,问题是我得到两次OnMouseDown事件:第一级项目和第二级项目。 例如,对于这棵树: 俄国      - 莫斯科      - Piter 美国     - 纽约      - 波士顿 如果我点击波士顿,我会先获得美国的比赛,然后是波士顿。所以,我无法区分这些案例:

  1. 当用户点击USA
  2. 当用户点击波士顿时,我刚刚获得隧道事件的第一部分
  3. 在TreeViewItem_OnMouseDown中,我需要知道用户点击的TreeViewItem。

    你能告诉我,我如何确定用户在TreeViewItem_OnMouseDown中点击的TreeViewItem?再说一次,如果我只是检查发件人。它可能是美国,但实际上用户点击了波士顿。所以我需要意识到这是波士顿。

1 个答案:

答案 0 :(得分:1)

嗯,这只是一个粗略的例子,但你可能会从后面的代码处理这样的事情。

<强> XAML

<TreeView ...>
    <TreeView.Resources>
        <Style TargetType="{x:Type TreeViewItem}">
            <EventSetter Event="PreviewMouseLeftButtonDown" Handler="treeViewItem_PreviewMouseLeftButtonDown" />
        </Style>
    </TreeView.Resources>
    ...
</TreeView>

一些助手方法

public static T GetFirstAncestorOfType<T>(DependencyObject source) where T : class
{
    while (source != null && !(source is T))
        source = VisualTreeHelper.GetParent(source);
    return source as T;
}

public static MessageBoxResult DoYouAgreeToMoveToAnotherItem()
{
    return MessageBox.Show("Select a different item?", "Select?", MessageBoxButton.YesNo);
}

代码背后

private TreeViewItem _selectedItem = null;

void treeViewItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    TreeViewItem tvi = GetFirstAncestorOfType<TreeViewItem>(e.OriginalSource as DependencyObject);

    if (_selectedItem != null &&
        tvi != null &&
        tvi != _selectedItem &&
        MessageBoxResult.Yes != DoYouAgreeToMoveToAnotherItem())
    {
        e.Handled = true;
    }
    else
    {
        // Update _selectedItem for comparison the next time this method fires.
        _selectedItem = tvi;
        if(_selectedItem != null)
            _selectedItem.IsSelected = true;
    }
}

您也可以使用纯MVVM来完成此操作。我没有时间使用TreeView发布示例,但解决方案可能涉及使用Dispatcher之类的解决方案...

WPF: Cancel a user selection in a databound ListBox?