UIElement.IsVisible == false用于自定义控件,无法对焦

时间:2012-11-21 14:17:43

标签: c# wpf custom-controls

我有一个源自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);

这也没有帮助。

3 个答案:

答案 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会触发,从那时起,它似乎工作得很好