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

时间:2009-12-29 15:16:37

标签: wpf button

我在下面的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方法之后在线上设置断点时,按下okay按钮时不会触发断点。仅当我按下Cancel按钮或关闭窗口时。

对不知情的建议?

2 个答案:

答案 0 :(得分:26)

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

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

(设置DialogResult也会关闭窗口)

答案 1 :(得分: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);
    }
}