Wpf - 默认按钮无法按预期工作

pho*_*tom 16 wpf button

我在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>
Run Code Online (Sandbox Code Playgroud)

我使用以下代码调用上面的窗口:

var p = new GraphicSizeSelectPopUp();
var result = p.ShowDialog() ?? false;
p.Close();
Run Code Online (Sandbox Code Playgroud)

Popup在我的应用程序中使用它作为一个窗口来从用户那里获取一些信息.我的问题是,当我点击OK按钮时,没有任何反应.该Cancel按钮完全按预期工作,这意味着控件从ShowDialog方法返回调用程序.

据我所知,WPF(还是新手),我所要做的就是将IsDefault属性设置为true,默认按钮也可以这样做.但是,这不是我所看到的.当我在ShowDialog方法之后的行上设置断点时,按下okay按钮时不会触发断点.只有当我按下Cancel按钮或关闭窗口时.

对不知情的建议?

Tho*_*que 26

IsDefault属性仅表示按下ENTER键时"单击"此按钮.它没有关闭对话框,也没有设置DialogResult,你必须在代码隐藏中手动完成:

private void BtnOK_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = true;
}
Run Code Online (Sandbox Code Playgroud)

(设置DialogResult也关闭窗口)

  • 与设置DialogResult的IsCancel不一致.顺便说一句,设置DialogResult就足够了,设置它会关闭窗口. (11认同)

小智 8

为了使事情更好,你可以使用像这样的附加属性:

<Button Content="OK" IsDefault="True" local:DialogBehaviours.OkButton="true" 
Height="23" HorizontalAlignment="Left" Width="75" />
Run Code Online (Sandbox Code Playgroud)

附加属性可以定义为:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)