سؤال

I want to bind a focus behavior to a reset button that will put the focus on the control named in the ElementToFocus property

<Style TargetType="Button" x:Key="Button_Reset" BasedOn="{StaticResource Button_Default}" >
        <Setter Property="ElementToFocus" />
        <Setter Property="behaviors:EventFocusAttachment.ElementToFocus" Value="{Binding ElementName=ElementToFocus}" />
</Style>

Control Markup:

<Button
    x:Name="button_Clear"
    Style="{DynamicResource Button_Reset}"
    HorizontalAlignment="Right"
    Content="Clear"
    Command="{Binding Path=ClearCommand}"  
    ElementToFocus="textbox_SearchText"
    Margin="0,0,0,7" />

How can I accomplish this?

هل كانت مفيدة؟

المحلول

I have created an attached behavior to try and achieve what you are trying to do.

Attached Behavior Code:

public static class ElementFocusBehavior
    {
        public static readonly DependencyProperty ElementToFocusProperty =
            DependencyProperty.RegisterAttached("ElementToFocus", typeof (FrameworkElement), typeof (ElementFocusBehavior), new PropertyMetadata(default(FrameworkElement), PropertyChangedCallback));

        private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var button = dependencyObject as Button;
            if (button == null) return;
            if (button.IsLoaded)
            {
                AddClickHandler(button);
            }
            else
            {
                button.Loaded += ButtonOnLoaded;
            }
        }

        private static void ButtonOnLoaded(object sender, RoutedEventArgs routedEventArgs)
        {
            var button = (Button) sender;
            button.Loaded -= ButtonOnLoaded;

            AddClickHandler(button);
        }

        static void AddClickHandler(Button button)
        {
            button.Click += ButtonOnClick;
        }

        private static void ButtonOnClick(object sender, RoutedEventArgs routedEventArgs)
        {
            var fe = GetElementToFocus(sender as Button) as FrameworkElement;
            if (fe == null) return;
            fe.Focus();
        }

        public static void SetElementToFocus(Button button, FrameworkElement value)
        {
            button.SetValue(ElementToFocusProperty, value);
        }

        public static FrameworkElement GetElementToFocus(Button button)
        {
            return (FrameworkElement) button.GetValue(ElementToFocusProperty);
        }
    }

And the XAML for Button:

<Button Content="Reset" local:ElementFocusBehavior.ElementToFocus="{Binding ElementName=TextBoxThree, Path=.}" />

Sample code from my MainWindow:

<StackPanel>
        <TextBox Name="TextBoxOne" />
        <TextBox Name="TextBoxTwo" />
        <TextBox Name="TextBoxThree" />
        <Button Content="Reset" local:ElementFocusBehavior.ElementToFocus="{Binding ElementName=TextBoxThree, Path=.}" />
    </StackPanel>

Basically, what I did was,

  1. have an attached behavior to store the element to be focused,
  2. and then in the attached behavior add event handler to button Click event,
  3. in the Click event set the Focus on the ElementToFocus element

Hope this helps.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top