简体   繁体   English

如何以编程方式选择聚焦元素?

[英]How can I programmatically select the focused element?

There is a page on which there are several focusable elements(Buttons, Images, ...) generated some statically in XAML, some dynamically in code behind. 有一个页面上有几个可聚焦元素(按钮,图像,...)在XAML中静态生成,一些动态地在代码后面生成。 On this page, pressing the tab key will make the elements focused one by one. 在此页面上,按Tab键将逐个聚焦元素。 That means the dotted lined gets displayed around the current element. 这意味着在当前元素周围显示虚线。 Now, I would like to make the current focused element, selected too. 现在,我想要选出当前的焦点元素。 That means to display the blueish line around it too. 这意味着也要在它周围显示蓝线。 So as the focused moves, so does the selected 因此,当重点移动时,所选择的移动也是如此

How can I do that in the C# code-behind? 我怎么能在C#代码隐藏中做到这一点?

在此输入图像描述

I would say the best way to do it perhaps varies depending on what kinds of focusable elements you have? 我想说最好的方法可能会有所不同,具体取决于你有哪些可聚焦元素? If you want to do this for listboxitem's, you can do this with only xaml like so: 如果你想为listboxitem做这个,你可以只用xaml这样做:

<UserControl.Resources>
    <Style TargetType="ListBoxItem">
        <Style.Triggers>
            <Trigger Property="IsFocused" Value="True">
                <Setter Property="Selector.IsSelected" Value="True"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>
<ListBox>
    <ListBoxItem>
        Blah
    </ListBoxItem>
</ListBox>

A similar style trigger can be applied for other focusable and selectable elements as well. 类似的样式触发器也可以应用于其他可聚焦和可选择的元素。

Edited: 编辑:

I think what you just need is change the dotted line on TabStop. 我认为你需要的是改变TabStop上的虚线。 That broken line is indicative of selected state. 该虚线表示选定的状态。 So, it is selected already. 所以,它已被选中。 This 'select the focused element' statement does not make any sense since if you are referring to TabStop, it is indeed already selected. 这个'选择聚焦元素'语句没有任何意义,因为如果您指的是TabStop,它确实已被选中。 You can test it by pressing the Tab and then whichever has the dotted line, if it is a button and hit enter, it will do the Click event (if there is ever a handler behind it). 您可以通过按Tab键然后按虚线来测试它,如果它是一个按钮并按Enter键,它将执行Click事件(如果它背后有一个处理程序)。

What you need is this . 你需要的是这个

If you want to do it in code behind, add this to the Resource of your XAML. 如果要在后面的代码中执行此操作,请将其添加到XAML的资源中。

<Style x:Key="MyFocusVisual">
      <Setter Property="Control.Template">
          <Setter.Value>
              <ControlTemplate>
                   <Rectangle Margin="-2" StrokeThickness="1" Stroke="Blue" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
</Style>
....
 myButton.FocusVisualStyle = (Style)FindResource("MyFocusVisual");

If you do not have an access to the XAML, I think from this, you can figure out how to add a style in code-behind and add the style to the button. 如果你没有XAML的访问权限,我想从中可以看出如何在代码隐藏中添加样式并将样式添加到按钮中。 Now, I am obviously contradicting myself here, since you are aiming for a code-behind, it is impossible not to have access to the XAML right? 现在,我显然在这里自相矛盾,因为你的目标是代码隐藏,不可能不能访问XAML吗? It is still practical to add this via XAML than code behind. 通过XAML添加它比使用后面的代码更实用。

I would ensure that every element is either a button or the template of a button. 我会确保每个元素都是按钮或按钮的模板。 This way the "IsTabStop" can be used, or the elements can be focused. 这样可以使用“IsTabStop”,或者可以聚焦元素。 Using the solution of MrsEd you can get the item to be correctly bordered: 使用MrsEd的解决方案,您可以使项目正确镶边:

<Button x:Class="Visualisation.UserControlButtonImage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             IsTabStop="True">
    <Button.Template>
        <ControlTemplate>
           <Grid>
               <Image/> 
           </Grid>
        </ControlTemplate>
    </Button.Template>
</Button>

What I did in the xml. 我在xml中做了什么。 I added PreviewGotKeyboardFocus to my window 我将PreviewGotKeyboardFocus添加到了我的窗口

             PreviewGotKeyboardFocus="FrmBase_OnPreviewGotKeyboardFocus"

Use PreviewGotKeyboardFocus on the root element (usercontrol or window) to handle the focus event on every child control. 在根元素(usercontrol或window)上使用PreviewGotKeyboardFocus来处理每个子控件上的焦点事件。

Code behind 代码背后

private void FrmBase_OnPreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    try
    {
        dynamic item = e.NewFocus;
        item.IsSelected = true;
    }
    catch (Exception ex)
    {

    }
}

The type of elements you are referring to, are not all selectable. 您引用的元素类型并非全部可选。

You want this in C#, and some elements will be added dynamically, and the keyboard will tab through the elements. 你想在C#中使用它,并且会动态添加一些元素,键盘将标记元素。 I suggest keeping track of your focused items and then implementing a method that does whatever it is you are trying to do based on the current focused element. 我建议跟踪你关注的项目,然后实现一个方法,根据当前关注的元素做你正在尝试做的事情。 Using the keyboard focus method. 使用键盘焦点方法。

protected override void OnPreviewGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
    var focusedElement = e.Source as IInputElement;
    // Do something here
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM