2

我有一个从 System.Windows.Controls.Control 派生的自定义 wpf 控件,它在大多数情况下都做得很好。

然而,有时在调用 UIElement.Focus() 的控件上调用 x.Focus() 会返回 false 并且不会聚焦控件。

经过一番挖掘,我发现

var x = control as FrameworkElement;
var focusable = x.Focusable; // -> true
var enabled = x.IsEnabled;  // -> true
var visible = x.IsVisible; // -> FALSE <- !!! ARRGG

控件已渲染,我完全可以在 UI 中看到它。我尝试将 Focus() 的调用放到 Dispatcher,尝试在控件上调用 UpdateLayout() 都没有帮助。

最有趣的部分是,如果我使用 Snop 检查 IsVisible 属性,Snoop 会报告它为 True :)

我是否遗漏了一些明显的东西,在我的控制实现或其他地方?

编辑 22.11.2012

感谢到目前为止的评论,对于那些建议控件可能尚未完全呈现的评论

var x = control as FrameworkElement;
x.Dispatcher.Invoke(new Action(() =>
{
var isVisible = fe.IsVisible; // -> False
var focused = fe.Focus(); // -> False
}), DispatcherPriority.ApplicationIdle);

这也没有帮助。

4

3 回答 3

1

检查 MSDN 文档中的所有overrides 并确保在需要时调用基类的方法。

我只是遇到了同样的问题,在几乎发疯后我发现了罪魁祸首:我正在重写OnVisualParentChanged并且没有调用基类(FrameworkElement在我的情况下),即使 MSDN 明确指出:

始终调用基本实现以保留此行为,否则当声明为另一个元素的子元素时,此元素的元素树行为可能与预期不同。

添加对属性的调用后base.OnVisualParentChangedIsVisible事件IsVisibleChanged开始按预期运行。

于 2014-08-20T01:10:38.030 回答
0

你什么时候检查 IsVisible 看它是假的?控件是否已完全初始化和加载?如果 snoop 认为它是真的,那么它一定是:) 你什么时候尝试集中控制?如果您在它未完全初始化时尝试集中它,则可能有合理数量的原因它不起作用。

无论如何,尝试通过Keyboard.Focus方法而不是使用UIElement.Focus来选择您的控件。

Keyboard.Focus(x);
于 2012-11-21T14:22:55.403 回答
0

我有同样的问题,不知道是什么原因造成的。我通过解决方法修复了它。

我在样式中将 Visibility 设置为 Collapsed,然后在 Loaded 事件中将其设置为 Visible。我意识到这并不适合所有用途,但如果其他人遇到此问题,那么您可以尝试此解决方法来解决它。

 // Set to visible on load
 Loaded += delegate
 {
     Dispatcher.BeginInvoke(new Action(() => Visibility = Visibility.Visible));
 };


 <!-- By default set to Collapsed -->
 <Style TargetType="{x:Type MyCustomTypeThatIsMisbehaving}">
    <Setter Property="Visibility" Value="Collapsed"/>
 </Style>

当控件可见时, IsVisibleChanged 触发,从那时起,它似乎工作得很好

于 2013-07-12T21:05:22.887 回答