Динамически изменить FocusManager.FocusedElement

У меня есть код WPF xaml, как показано ниже:

  <StackPanel  FocusManager.FocusedElement="{Binding FocusedElement}">
    <TextBox Name="txtbox1" Text="FirstText"/>
    <TextBox Name="txtbox3" Text="SecondText"/>
    <TextBox Name="txtbox2" Text="ThirdText"/>
  </StackPanel>

Как я могу привязать FocusedElement к свойству во ViewModel? похожий код ниже:

Switch(Type)
{
Case "FirstType" :
  FocusedElement = "txtbox1";
break;
Case "SecondType" :
   FocusedElement = "txtbox2";
break;
Case "ThiredType" :
   FocusedElement = "txtbox3";
break;
}

2 ответа

Решение

Модель представления никогда не должна знать о представлении и совершенно точно не должна знать некоторые имена UIElement. Но, учитывая, что модель представления действительно должна иметь возможность управлять фокусом (я предлагаю вам убедиться, что это действительно так, прежде чем продолжить), вы можете сделать что-то вроде этого:

введите описание изображения здесь

ViewModel:

public enum Focuses
{
    None = 0,
    First,
    Second,
    Third
}

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private Focuses _focusedElement;
    public Focuses FocusedElement { get { return _focusedElement; } set { _focusedElement = value; OnPropertyChanged("FocusedElement"); } }


    public ViewModel()
    {
        this.FocusedElement = Focuses.Second;
    }
}

Xaml:

<StackPanel >
    <TextBox Name="txtbox1" Text="FirstText"/>
    <TextBox Name="txtbox2" Text="SecondText"/>
    <TextBox Name="txtbox3" Text="ThirdText"/>
    <StackPanel.Style>
        <!-- cannot use DataTriggers directly in StackPanel.Triggers, therefore Style -->
        <Style TargetType="{x:Type StackPanel}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding FocusedElement}" Value="First">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=txtbox1}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding FocusedElement}" Value="Second">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=txtbox2}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding FocusedElement}" Value="Third">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=txtbox3}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </StackPanel.Style>
</StackPanel>

FocusedElement - это элемент, который имеет логический фокус для определенной области фокусировки.

Логический фокус, а не "реальный фокус", такой как txtBox1.Focus();

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

Вам действительно нужен логический фокус?

Вы можете прослушать событие GotFocus, а затем сделать некоторую пользовательскую логику в качестве примера.

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