Wpf - 默认按钮未按预期工作

17

以下是我的XAML代码,其中默认的Button出现了问题:

<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按钮或关闭窗口时才会触发。

对于不了解情况的人有建议吗?

2个回答

28

IsDefault属性仅表示当按下 ENTER 键时,此按钮将被“单击”。它不会关闭对话框,也不会设置DialogResult,您需要在代码后台手动执行:

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

(设置 DialogResult 也会关闭窗口)


12
与设置DialogResult的IsCancel不是非常一致。顺便说一下,设置DialogResult就足够了,设置它会关闭窗口。 - Ignacio Soler Garcia

8
为了让事情更美好,你可以使用一个附加属性,像这样:

<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);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接