Как установить RadioButton.IsChecked, если он находится в фокусе Content - PullRequest
0 голосов
/ 05 августа 2020

В моем приложении WPF у меня есть группа RadioButton s, где один из элементов определяется следующим образом:

<RadioButton Grid.Row="2" Grid.Column="1"
                Margin="5"
                HorizontalContentAlignment="Stretch"
                GroupName="GroupDatetimeTo">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0"
                    Margin="5,5,15,5"
                    VerticalAlignment="Center"
                    Text="Exactly">
        </TextBlock>

        <mah:DateTimePicker Grid.Column="1"
                            Margin="5"
                            VerticalAlignment="Center" HorizontalAlignment="Stretch"
                            SelectedDateTime="{Binding Path=DatetimeTo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        </mah:DateTimePicker>
    </Grid>
</RadioButton>

Я ожидал бы, что когда DateTimePicker элемент управления будет сфокусирован - RadioButton будет автоматически проверяться. Однако этого не происходит. Как я могу это исправить?

1 Ответ

0 голосов
/ 05 августа 2020

Состояние проверки привязки

Вы можете добавить привязку к свойству IsChecked, которое отслеживает фокус клавиатуры DateTimePicker.

<RadioButton IsChecked="{Binding ElementName=MyDateTimePicker, Mode=OneWay, Path=IsKeyboardFocusWithin}" ... >

Здесь MyDateTimePicker - имя из DateTimePicker в вашем RadioButton.

<mahapps:DateTimePicker x:Name="MyDateTimePicker" ... />

Это решение неприменимо, если вам нужно привязать IsChecked в противном случае.

Проверить сфокусированное присоединенное свойство

Другое решение - создать присоединенное свойство, которое можно включить для наблюдения, когда элемент управления, к которому он присоединен, получает фокус клавиатуры. Затем он ищет в визуальном дереве родительский RadioButton и устанавливает IsChecked на true. Таким образом, вы все еще можете привязать свойство.

public static class RadioButtonProperties
{
   public static readonly DependencyProperty CheckOnFocusProperty = DependencyProperty.RegisterAttached(
      "CheckOnFocus", typeof(bool), typeof(RadioButtonProperties), new PropertyMetadata(false, OnCheckOnFocusChanged));

   private static void OnCheckOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   {
      if (!(d is FrameworkElement frameworkElement))
         return;

      if ((bool)e.NewValue)
         frameworkElement.GotKeyboardFocus += OnGotKeyboardFocus;
      else
         frameworkElement.GotKeyboardFocus -= OnGotKeyboardFocus;
   }

   public static bool GetCheckOnFocus(DependencyObject dependencyObject)
   {
      return (bool)dependencyObject.GetValue(CheckOnFocusProperty);
   }

   public static void SetCheckOnFocus(DependencyObject dependencyObject, bool value)
   {
      dependencyObject.SetValue(CheckOnFocusProperty, value);
   }

   private static void OnGotKeyboardFocus(object sender, RoutedEventArgs e)
   {
      var radioButton = FindParent<RadioButton>((DependencyObject)sender);
      if (radioButton != null)
         radioButton.IsChecked = true;
   }

   private static T FindParent<T>(DependencyObject child) where T : DependencyObject
   {
      var parentObject = VisualTreeHelper.GetParent(child);

      if (parentObject == null)
         return null;

      if (parentObject is T parent)
         return parent;

      return FindParent<T>(parentObject);
   }
}

Чтобы включить его, установите для прикрепленного свойства CheckOnFocus значение True на целевом DateTimePicker.

<mahapps:DateTimePicker local:RadioButtonProperties.CheckOnFocus="True" ...>
...