我有一个具有 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 事件:第一级项目和第二级项目。 例如,对于这棵树: 俄罗斯 - 莫斯科 - 彼得 美国 - 纽约 - 波士顿 如果我单击波士顿,我将获得美国的第一个事件,然后是波士顿的事件。所以,我无法区分大小写:
- 当用户点击美国时
- 当用户点击 Boston 时,我得到了隧道事件的第一部分
在 TreeViewItem_OnMouseDown 中,我需要知道用户点击了哪个 TreeViewItem。
你能告诉我,我如何确定用户在 TreeViewItem_OnMouseDown 中点击的 TreeViewItem 吗?同样,如果我只是检查发件人。它可能是美国,但实际上用户点击了波士顿。所以我需要意识到那是波士顿。
最佳答案
好吧,这只是一个粗略的示例,但您可以从后面的代码中像这样处理它。
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
,类似于此处提供的解决方案...
关于c# - 如何防止 TreeViewItem 选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18577565/