有没有一种方法来设定 Focus 从一个控制另一个使用WPF Triggers?

如以下例子:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid>  
    <Grid.RowDefinitions>
      <RowDefinition/>
      <RowDefinition/>
      <RowDefinition/>
    </Grid.RowDefinitions>

    <TextBox Name="txtName"></TextBox>    
    <TextBox Grid.Row="1" Name="txtAddress"></TextBox>
    <Button Grid.Row="2" Content="Finish">
        <Button.Triggers>
            <EventTrigger RoutedEvent="Button.Click">

                <!-- Insert cool code here-->  

            </EventTrigger>
        </Button.Triggers>
    </Button>
  </Grid>
</Page>

有没有办法为这个 EventTrigger 把重点放在文本框"txtName"?

我试图找到办法做这样的事情使用严格。.如果是这样的东西,不应通过XAML(在。)然后这是好的。但我想看到的一些样的文件如何配合在模式。这样做以外的停靠。

有帮助吗?

解决方案

你有没有使用附加的行为考虑。他们是简单的实现和使用AttachedProperty的。虽然它仍然需要代码,这个代码在一个类中抽象出来,并可以重复使用。他们可以无需“后面代码”和通常与MVVM模式使用。

试试这个,看看它是否适合你。

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 UIPropertyMetadata(null, ElementToFocusPropertyChanged));

    public static void ElementToFocusPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var button = sender as Button;
        if (button != null)
        {
            button.Click += (s, args) =>
                {
                    Control control = GetElementToFocus(button);
                    if (control != null)
                    {
                        control.Focus();
                    }
                };
        }
    }
}

然后在你的XAML做这样的事情...

<Button 
    Content="Click Me!" 
    local:EventFocusAttachment.ElementToFocus="{Binding ElementName=textBox}" 
    />
<TextBox x:Name="textBox" />

其他提示

我不靠近视觉工作室,所以我不能真正尝试这个权利,但把我的头顶部,你应该能够做这样的事:

FocusManager.FocusedElement="{Binding ElementName=txtName}">

编辑:

有一个后续问题(最近问)这个位置:如何仅在XAML组自动聚焦?其中包含此方法,并在几个不同的想法如何使用它。

您也可以使用WPF行为...

    public class FocusElementAfterClickBehavior : Behavior<ButtonBase>
{
    private ButtonBase _AssociatedButton;

    protected override void OnAttached()
    {
        _AssociatedButton = AssociatedObject;

        _AssociatedButton.Click += AssociatedButtonClick;
    }

    protected override void OnDetaching()
    {
        _AssociatedButton.Click -= AssociatedButtonClick;
    }

    void AssociatedButtonClick(object sender, RoutedEventArgs e)
    {
        Keyboard.Focus(FocusElement);
    }

    public Control FocusElement
    {
        get { return (Control)GetValue(FocusElementProperty); }
        set { SetValue(FocusElementProperty, value); }
    }

    // Using a DependencyProperty as the backing store for FocusElement.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FocusElementProperty =
        DependencyProperty.Register("FocusElement", typeof(Control), typeof(FocusElementAfterClickBehavior), new UIPropertyMetadata());
}

下面是使用行为XAML。

包含名称空间:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:local="clr-namespace:WpfApplication1"

附加WPF行为到按钮并结合元件要焦点设置到:

<Button Content="Focus" Width="75">
    <i:Interaction.Behaviors>
        <local:FocusElementAfterClickBehavior FocusElement="{Binding ElementName=CheckBoxComboBox, Mode=OneWay}"/>
    </i:Interaction.Behaviors>
</Button>
<ComboBox x:Name="CheckBoxComboBox" HorizontalAlignment="Center" VerticalAlignment="Center" Width="120" Grid.Row="1"/>

所以这样你背后没有代码,它是可重复使用的对自ButtonBase继承任何控制。

希望这可以帮助别人。

需要一个TriggerAction调用焦点()方法所需的控制。

public class SetFocusTrigger : TargetedTriggerAction<Control>
{
 protected override void Invoke(object parameter)
 {
    if (Target == null) return;

    Target.Focus();
 }
}

要设置有一个控制的重点,你把一个触发器收集您的LayoutRoot(或任何控制真)后,选择事件作为触发,并选择SetFocusTrigger作为类运行。在SetFocusTrigger声明,你把你想要使用的TargetName属性接收焦点的控件的名称。

<Button x:Name="LayoutRoot" >
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Clicked">
        <local:SetFocusTrigger TargetName="StartHere"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

<TextBox x:Name="StartHere"/>
</Button>

这是你想要的吗?

    <TextBox Name="txtName"></TextBox>
    <TextBox Grid.Row="1" Name="txtAddress"></TextBox>
    <Button Grid.Row="2" Content="Finish">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <EventSetter Event="Click" Handler="MoveFocusOnClick" />
            </Style>
        </Button.Style>
        <!--<Button.Triggers>
            <EventTrigger RoutedEvent="Button.Click">
            </EventTrigger>
        </Button.Triggers>-->
    </Button>

C#:

    public void MoveFocusOnClick(object sender, RoutedEventArgs e)
    {
        Keyboard.Focus(txtName); // Or your own logic
    }

这是同伊恩*奥克斯'的解决方案,但是我做了几个微小的变化。

  1. 按钮的类型可以是更一般的,即 ButtonBase, ,来处理更多的案件,例如 ToggleButton.
  2. 目标类型,也可以更一般的,即 UIElement.从技术上讲,这可能是 IInputElement, 我假设。
  3. 由的事件的处理程序静态的,所以它不会产生一个运行时关闭每一个时间,这是使用。
  4. [编辑:2019年]更新,以使用null条件和C#7表达的身体语法。

非常感谢伊恩。


public sealed class EventFocusAttachment
{
    public static UIElement GetTarget(ButtonBase b) => (UIElement)b.GetValue(TargetProperty);

    public static void SetTarget(ButtonBase b, UIElement tgt) => b.SetValue(TargetProperty, tgt);

    public static readonly DependencyProperty TargetProperty = DependencyProperty.RegisterAttached(
            "Target",
            typeof(UIElement),
            typeof(EventFocusAttachment),
            new UIPropertyMetadata(null, (b, _) => (b as ButtonBase)?.AddHandler(
                ButtonBase.ClickEvent,
                new RoutedEventHandler((bb, __) => GetTarget((ButtonBase)bb)?.Focus()))));
};

使用基本上是相同的:

<ToggleButton z:EventFocusAttachment.Target="{Binding RelativeSource={RelativeSource Self}}" />

注意到事件可能目标/注重起始按钮本身。

看,如果你正在使用的任何分派那么这将是有益的,但,这是很短的把戏我在代码中使用。只需使用Loaded事件在您的XAML,并作出新的处理程序。在该处理程序粘贴此代码和宾果!你已经准备好

您在这里一些参数加载事件......

{
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, new System.Action(() => {
        The element to be focused goes here......
    }));
}

PS:它需要视窗。如果线程你不知道;)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top