如何检测控件变得可见的时刻

How to detect a moment when the control becomes visible

我正在使用 MVVM。在我的视图中,我有一个默认隐藏的控件,它的可见性 属性 绑定到 ViewModels 属性.

<Grid>
    <TextBox Visibility={Binding IsVisible, Mode=OneWay, Converter={StaticResource MyVisibilityConverter}}/>
<Grid>

在 ViewModel 中我有一个 属性

private bool _isVisible;
bool IsVisible
{
    get {return _isVisible;}
    set {_isVisible = value; NotifyOfPropetyChanged(() => IsVisible);}
}

相当直截了当,展示我刚刚做的控制

IsVisible = true;

在我的 ViewModel 中,TextBox 变得可见,按预期工作正常。

我想做的是在 TextBox 可见后立即将其设置为 Focus。问题是我找不到任何好的解决方案来确定这个特定的控件是否可见,而这是我可以设置焦点的时刻。 解决方案是测试 LayoutUpdated 事件中的可见性,但这绝对不是代码中最好的东西。 有更好的解决方案吗?

编辑: 澄清一下——我不想通过 ViewModel 的 MVVM 设置焦点。从代码隐藏设置焦点没有问题,因为它是 UI 行为。唯一的问题是如何确定何时执行此操作。在设置 ViewModel 属性 和更新布局以匹配其状态之间有一段时间。在那段时间之后,我希望能够捕捉到任何可以通知我的东西 "my visibility has changed, now you can change focus"

您可以使用 RegisterPropertyChangedCallback 为文本框的可见性 属性 注册更改回调。然后在更改后的回调方法中,您可以设置焦点是否可见。

将其放在后面代码的构造函数中:

TextBox1.RegisterPropertyChangedCallback(UIElement.VisibilityProperty, VisibilityChanged);

并添加回调方法:

private void VisibilityChanged(DependencyObject sender, DependencyProperty dp)
{
  if (((UIElement)sender).Visibility == Visibility.Visible)
  {
    TextBox1.Focus(FocusState.Keyboard);
  }
}