Подтвердить что ты не робот

Wpf - кнопка по умолчанию не работает как ожидаемая

У меня возникла проблема с по умолчанию Button в коде xaml ниже:

<Window x:Class="WebSiteMon.Results.Views.GraphicSizeSelectPopUp"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:commonWPF="http://rubenhak.com/common/wpf"
        xmlns:WPF="clr-namespace:Bennedik.Validation.Integration.WPF;assembly=Bennedik.Validation.Integration.WPF"
        ResizeMode="NoResize"
        WindowStyle="ThreeDBorderWindow"
        SizeToContent="WidthAndHeight">
  <Window.Resources>
    <Style TargetType="{x:Type TextBox}">
      <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
          <ControlTemplate>
            <Border BorderBrush="Red"
                    BorderThickness="2">
              <AdornedElementPlaceholder />
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
      <Style.Triggers>
        <Trigger Property="Validation.HasError"
                 Value="true">
          <Setter Property="ToolTip"
                  Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
        </Trigger>
      </Style.Triggers>
    </Style>
  </Window.Resources>
  <WPF:ErrorProvider x:Name="UrlDataErrorProvider"
                     RulesetName="RuleSetA">
    <Grid Background="{DynamicResource WindowBackgroundBrush}">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="25" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
      </Grid.RowDefinitions>

      <RadioButton Grid.ColumnSpan="2"
                   Margin="10"
                   Name="radioButton1"
                   Content="640 x 480 pixels"
                   Command="{Binding SelectSizeRb}"
                   CommandParameter="640,480" />
      <RadioButton Grid.ColumnSpan="2"
                   Margin="10"
                   Name="radioButton2"
                   Content="800 x 600 pixels"
                   Command="{Binding SelectSizeRb}"
                   CommandParameter="800,600"
                   Grid.Row="1"
                   IsChecked="True" />
      <RadioButton Grid.ColumnSpan="2"
                   Margin="10"
                   Name="radioButton3"
                   Content="1024 x 768 pixels"
                   Command="{Binding SelectSizeRb}"
                   CommandParameter="1024,768"
                   Grid.Row="2" />
      <RadioButton Grid.ColumnSpan="2"
                   Margin="10"
                   Name="radioButton4"
                   Command="{Binding SelectSizeRb}"
                   CommandParameter="0,0"
                   Grid.Row="3" />

      <Button Grid.Column="1"
              Grid.ColumnSpan="1"
              Grid.Row="5"
              Margin="5"
              Name="BtnOk"
              IsDefault="True">Ok</Button>
      <Button Grid.Column="2"
              Grid.ColumnSpan="1"
              Grid.Row="5"
              Margin="5"
              Name="BtnCancel"
              IsCancel="True">Cancel</Button>

    </Grid>
  </WPF:ErrorProvider>
</Window>

Я вызываю указанное выше окно, используя следующий код:

var p = new GraphicSizeSelectPopUp();
var result = p.ShowDialog() ?? false;
p.Close();

Я использую это как окно Popup в своем приложении, чтобы получить информацию от пользователя. Моя проблема в том, что когда я нажимаю кнопку OK, ничего не происходит. Кнопка Cancel работает точно так, как ожидалось, что означает, что управление возвращается в вызывающей программе из метода ShowDialog.

Как я понимаю, WPF (все еще новичок), все, что мне нужно сделать, это установить для свойства IsDefault значение true для кнопки по умолчанию, чтобы сделать то же самое. Однако это не то, что я вижу. Когда я устанавливаю точку останова на линии после метода ShowDialog, она не ударяется, когда я нажимаю кнопку "ОК". Только когда я нажимаю кнопку Cancel или закрываю окно.

Предложения для неосведомленного?

4b9b3361

Ответ 1

Свойство IsDefault означает, что эта кнопка нажата, когда нажата клавиша ENTER. Он не закрывает диалоговое окно и не устанавливает DialogResult, вы должны сделать это вручную в кодировке:

private void BtnOK_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = true;
}

(установка DialogResult также закрывает окно)

Ответ 2

Чтобы сделать все лучше, вы можете использовать прикрепленное свойство, подобное этому:

<Button Content="OK" IsDefault="True" local:DialogBehaviours.OkButton="true" 
Height="23" HorizontalAlignment="Left" Width="75" />

прикрепленное свойство может быть определено как таковое:

public class DialogBehaviours
{

    /*
        OkButton property.

        An attached property for defining the Accept (OK) button on a dialog.
        This property can be set on any button, if it is set to true, when enter is pressed, or
        the button is clicked, the dialog will be closed, and the dialog result will be set to
        true.
    */
    public static bool GetOkButton(DependencyObject obj)
    {return (bool)obj.GetValue(OkButtonProperty);       }

    public static void SetOkButton(DependencyObject obj, bool value)
    {obj.SetValue(OkButtonProperty, value);     }

    public static readonly DependencyProperty OkButtonProperty =
        DependencyProperty.RegisterAttached("OkButton", typeof(bool), typeof(Button), new UIPropertyMetadata(false, OnOkButtonPropertyChanged_));

    static void OnOkButtonPropertyChanged_(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is Button) || !(e.NewValue is bool))
            return;

        Button button = (Button)obj;
        bool value = (bool)e.NewValue;

        if (value)
            button.Click += OnAcceptButtonClicked_;
        else
            button.Click -= OnAcceptButtonClicked_;

        button.IsDefault = value;
    }

    static void OnAcceptButtonClicked_(object sender, RoutedEventArgs e)
    {
        if (!(sender is DependencyObject))
            return;

        Window parent = FindParent<Window>((DependencyObject)sender, (c) => true);
        if (parent != null)
        {
            try { parent.DialogResult = true; }
            catch (Exception)
            {
                parent.Close();
            }
        }
    }

    public static T FindParent<T>(DependencyObject obj, Predicate<T> predicate) where T : FrameworkElement
    {
        if (obj == null || predicate == null)
            return null;

        if (obj is T)
        {
            T control = (T)obj;
            if (predicate(control))
                return control;
        }

        DependencyObject parent = VisualTreeHelper.GetParent(obj);
        return (parent == null) ? null : FindParent<T>(parent, predicate);
    }
}