2009-12-29 41 views
16

我在与下面的XAML代码默认Button一个问题:WPF - 默认按钮无法正常运行

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

<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> 

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

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

据我所知,WPF(仍然是新手),我所要做的就是将默认按钮IsDefault属性设置为true,以执行相同操作。但是,这不是我所看到的。当我在ShowDialog方法之后在线上设置断点时,按下okay按钮时不会触及它。只有当我按下Cancel按钮或关闭窗口。

对不知情的?

回答

26

IsDefault属性仅表示当按下ENTER键时该按钮被“单击”。它不关闭对话框,并且不设置DialogResult,你必须做手工,在后台代码:

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

(设置DialogResult也关闭窗口)

+8

与设置DialogResult的IsCancel不太一致。顺便说一句,设置DialogResult就足够了,设置它关闭窗口。 – 2012-11-02 14:42:17

+0

@SoMoS,你当然是对的。我删除了关闭的电话。 – 2012-11-02 14:58:30

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