0

I am not very experienced using Behaviors, but so far they have come in handy to be able to execute code from the ViewModel but still triggering the actions from the View.

In my current scenario, I have a TextBox that appears when a Button is clicked. I would like to then set the focus of that TextBox after the Button has been clicked.

Previously, I have been able to set the focus using an EventTriggerBehavior like so:

<core:EventTriggerBehavior>
    <behaviors:FocusAction />
</core:EventTriggerBehavior>

However, this will only suffice if I want to set the focus of that control when the View is loaded. In this case, the TextBox isn't visible at that time, and actually, the focus goes to a different TextBox initially.

Is there a way to set the focus of a control from the ViewModel? This is a WinRT 8.1 application, but will be being ported to Windows 10 Universal in the future.

EDIT

The answer here looks like it would do what I am looking for, but when I try it I get an error:

Cannot resolve symbol 'UIPropertyMetadata'

From what I can tell, that class exists in the System.Windows namespace, but even with a using System.Windows; I still get the same error. I have also tried new System.Windows.UIPropertyMetadata(null, ElementToFocusPropertyChanged) as well, but that doesn't make a difference either. Is that class not available in WinRT?

Community
  • 1
  • 1
dub stylee
  • 3,252
  • 5
  • 38
  • 59

1 Answers1

0

I was able to get it to work by slightly modifying the answer linked to in my original question. For anyone looking to accomplish this in a WinRT application, here is the modified code:

public class EventFocusAttachment
{
    public static Control GetElementToFocus(Button button)
    {
        return (Control)button.GetValue(ElementToFocusProperty);
    }

    public static void SetElementToFocus(Button button, Control value)
    {
        button.SetValue(ElementToFocusProperty, value);
    }

    public static readonly DependencyProperty ElementToFocusProperty =
        DependencyProperty.RegisterAttached("ElementToFocus", typeof(Control),
        typeof(EventFocusAttachment), new PropertyMetadata(null, ElementToFocusPropertyChanged));

    public static void ElementToFocusPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var button = sender as Button;
        if (button != null)
        {
            button.Click += async (s, args) =>
            {
                var control = GetElementToFocus(button);
                if (control != null)
                {
                    await Task.Delay(100);
                    control.Focus(FocusState.Programmatic);
                }
            };
        }
    }
}

I had to add a small delay because the TextBox that I am focusing on is not visible until after the button is pressed, so it wasn't working without the delay. Also, I had to change the UIPropertyMetadata to simply PropertyMetadata, and add async to the lambda expression to allow for the await Task.Delay(100);

dub stylee
  • 3,252
  • 5
  • 38
  • 59