wpf 动态更改 FocusManager.FocusedElement

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15321047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:00:02  来源:igfitidea点击:

Change Dynamically FocusManager.FocusedElement

wpfbindfocusmanager

提问by oliver

I have WPF xaml code like below:

我有 WPF xaml 代码,如下所示:

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

How can I Bind FocusedElement to Property in ViewModel? similar code below:

如何将 FocusedElement 绑定到 ViewModel 中的属性?类似的代码如下:

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

回答by Mike Fuchs

The viewmodel should never know about the view, and quite certainly not know some UIElement names. But given that the viewmodel really needs to be able to manage focus (I suggest you make sure that really is the case before proceeding), you could do something like this:

视图模型永远不应该知道视图,当然也不应该知道一些 UIElement 名称。但是鉴于视图模型确实需要能够管理焦点(我建议您在继续之前确保确实如此),您可以执行以下操作:

enter image description here

在此处输入图片说明

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:

Xml:

<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>

回答by snowy hedgehog

The FocusedElement is the element which has logical focus for a specific focus scope.

FocusedElement 是具有特定焦点范围的逻辑焦点的元素。

The logical focus and not the "real focus" such as txtBox1.Focus();

逻辑焦点而不是“真正的焦点”,例如 txtBox1.Focus();

Logical focus can be set multiple times while only one element can have keyboard focus.

逻辑焦点可以设置多次,而只有一个元素可以有键盘焦点。

Do you really need the logical focus?

你真的需要逻辑焦点吗?

You can listen to GotFocus event and then do some custom logic as example.

您可以收听 GotFocus 事件,然后执行一些自定义逻辑作为示例。