我有一个源自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()并没有帮助。
最有趣的是,如果我使用Snnop检查IsVisible属性,Snoop会将其报告为True:)
在控制实施或其他地方,我是否遗漏了一些明显的东西?
EDIT 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);
这也没有帮助。
答案 0 :(得分:1)
检查所有override
的MSDN文档,并确保调用基类&#39;如果强制要求的方法。
我遇到了同样的问题,经过几乎疯了之后,我找到了罪魁祸首:我重写OnVisualParentChanged
并且不调用基类(FrameworkElement
在我的情况下),即使MSDN明确指出:
始终调用基本实现来保留此行为, 否则声明为此元素时的元素树行为 另一个元素的孩子可能不如预期。
将调用添加到base.OnVisualParentChanged
后,IsVisible
属性开始,IsVisibleChanged
事件开始按预期运行。
答案 1 :(得分:0)
你什么时候检查IsVisible看到它是假的?控件是否已完全初始化并加载?如果snoop认为它是真的那么它必须是:)你何时尝试集中控制?如果你在没有完全初始化的情况下尝试关注它,可能会有一些合理的理由它不会起作用。
无论如何,请尝试通过Keyboard.Focus方法选择您的控件,而不是使用UIElement.Focus。
Keyboard.Focus(x);
答案 2 :(得分: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会触发,从那时起,它似乎工作得很好