Search code examples
c#uwpwin-universal-app

How to detect a moment when the control becomes visible


I am using MVVM. On my View I have a control that by default is hidden, it's Visibility property is Binded to ViewModels property.

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

In the ViewModel I have a property

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

pretty much straighforward, to show the control I just do

IsVisible = true;

in my ViewModel and the TextBox becomes visible, works fine as intended.

What I want to do is to set Focus on the TextBox just after it becomes visible. The problem is that I can't find any good solution how to determine that this particular control just got visible and it is the moment I can set the focus. The solution would be to test the visibility inside LayoutUpdated event, but it is definitely not the nicest thing to have in code. Any better solution?

edit: To clarify - I don't want to set the focus via MVVM from the ViewModel. There is no problem in setting the focus from the code-behind as it is the UI behaviour. The only problem is how to determine WHEN to do that. There is a some period of time beetween the ViewModel property is set and the layout being updated to match its state. After that perdiod of time I want to be able to catch anything that can notify me "my visibility has changed, now you can change focus"


Solution

  • You could use RegisterPropertyChangedCallback to register a change callback for the Visibility property of the textbox. then in the changed call back method you can set the focus is the visibility is visible.

    Put this in the constructor of the code behind:

    TextBox1.RegisterPropertyChangedCallback(UIElement.VisibilityProperty, VisibilityChanged);
    

    and add the CallBack method:

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