Настройка фокуса в WPF с MVVM

У меня есть Grid с несколькими текстовыми полями. В зависимости от действий, которые пользователь может сфокусировать, его следует заменить одним из текстовых полей. Мое текущее решение использует строковое свойство в ViewModel и триггер данных в xaml для изменения фокуса. Это работает хорошо, но кажется довольно окольным путем для достижения этого, поэтому мне было интересно, можно ли сделать это более понятным способом?

    <Grid.Style>
        <Style TargetType="Grid">
            <Style.Triggers>
                <DataTrigger Binding="{Binding FocusedItem}" Value="number">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=number}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding FocusedItem}" Value="name">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=name}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding FocusedItem}" Value="id">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=id}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>

Как вы можете видеть, значение свойства и имя элемента совпадают, поэтому я хотел бы сделать это, например, один триггер вместо одного триггера на элемент.

Может быть, кто-то может придумать более чистый способ?

заранее спасибо

1 ответ

То, как я справился с настройкой фокуса в одном из моих проектов, было с помощью расширения фокуса (я извиняюсь, я не помню, где я увидел исходное сообщение, из которого оно было).

    public static class FocusExtension
    {
        public static bool GetIsFocused(DependencyObject obj)
        {
           return (bool)obj.GetValue(IsFocusedProperty);
        }


        public static void SetIsFocused(DependencyObject obj, bool value)
        {
            obj.SetValue(IsFocusedProperty, value);
        }


        public static readonly DependencyProperty IsFocusedProperty =
                DependencyProperty.RegisterAttached(
                 "IsFocused", typeof(bool), typeof(FocusExtension),
                 new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));


        private static void OnIsFocusedPropertyChanged(DependencyObject d,
                DependencyPropertyChangedEventArgs e)
        {
            var uie = (UIElement)d;
            if ((bool)e.NewValue)
            {
                uie.Focus();
            }
        }
    }

И затем в файле xaml я использую его как свойство зависимости:

<TextBox Uid="TB1" FontSize="13" localExtensions:FocusExtension.IsFocused="{Binding Path=TB1Focus}" Height="24" HorizontalAlignment="Left" Margin="113,56,0,0" Name="TB_UserName" VerticalAlignment="Top" Width="165" Text="{Binding Path=TB1Value, UpdateSourceTrigger=PropertyChanged}" />

Затем вы можете использовать привязку, чтобы установить фокус.

Другие вопросы по тегам