我在弹出窗口中有一个WPF CheckBox,但我发现它是否在TreeView的项目模板中,因此CheckBox不会响应用户输入.如果它在TreeView之外,则没有问题.
我在这里创建了一个相对最小的模型:
https://github.com/logiclrd/TestControlsInPopupsNotWorking
有谁知道为什么无法检查从TreeView中弹出的CheckBox控件?
解决方法:
我认为这是TreeView设计中的一个疏漏.看看这个:
注意:整理了一些代码摘录以避免换行.
// This method is called when MouseButonDown on TreeViewItem and also listen
// for handled events too. The purpose is to restore focus on TreeView when
// mouse is clicked and focus was outside the TreeView. Focus goes either to
// selected item (if any) or treeview itself
internal void HandleMouseButtonDown()
{
if (!this.IsKeyboardFocusWithin)
{
if (_selectedContainer != null)
{
if (!_selectedContainer.IsKeyboardFocused)
_selectedContainer.Focus();
}
else
{
// If we don't have a selection - just focus the TreeView
this.Focus();
}
}
}
从TreeViewItem.OnMouseButtonDown调用此方法,我们可以看到它是一个配置为也接收已处理事件的类级处理程序:
EventManager.RegisterClassHandler(
typeof(TreeViewItem),
Mouse.MouseDownEvent,
new MouseButtonEventHandler(OnMouseButtonDown),
/* handledEventsToo: */ true);
我已经使用调试器验证了事件到TreeViewItem时,Handled已设置为true.
当您按下CheckBox上方的鼠标左键时,CheckBox将开始进行推测性的“单击”操作,并将事件标记为已处理.通常,祖先元素不会看到已处理事件冒泡,但是在这种情况下,它明确要求它们.
TreeView看到this.IsKeyboardFocusWithin解析为false,因为聚焦的元素在另一棵可视树(弹出窗口)中.然后将焦点返回给TreeViewItem.
现在,如果您查看ButtonBase:
protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnLostKeyboardFocus(e);
if (ClickMode == ClickMode.Hover)
{
// Ignore when in hover-click mode.
return;
}
if (e.OriginalSource == this)
{
if (IsPressed)
{
SetIsPressed(false);
}
if (IsMouseCaptured)
ReleaseMouseCapture();
IsSpaceKeyDown = false;
}
}
我们看到失去焦点时将IsPressed设置为false.如果然后转到OnMouseLeftButtonUp,则会看到以下内容:
bool shouldClick = !IsSpaceKeyDown && IsPressed && ClickMode == ClickMode.Release;
如果IsPressed现在为false,则单击操作将永远不会完成,这是因为当您尝试单击按钮时,TreeViewItem会将焦点移到了您身上.