2009-12-29 7 views
16

Estoy teniendo un problema con el valor por defecto Button en el código XAML a continuación:Wpf - botón predeterminado no funciona como se esperaba

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

me llaman la ventana de arriba usando el siguiente código:

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

Estoy usando esto como una ventana Popup en mi aplicación para obtener información del usuario. Mi problema es que cuando hago clic en el botón OK, no pasa nada. El botón Cancel funciona exactamente como se esperaba, lo que significa que el control vuelve al programa de llamada desde el método ShowDialog.

Según entiendo WPF (aún novato), todo lo que tengo que hacer es establecer la propiedad IsDefault en true para que el botón predeterminado haga lo mismo. Sin embargo, esto no es lo que estoy viendo. Cuando establezco un punto de interrupción en la línea después del método ShowDialog, no se golpea cuando presiono el botón de Aceptar. Solo cuando presiono el botón Cancel o cierro la ventana.

Sugerencias para desinformados?

Respuesta

26

La propiedad IsDefault solo significa que este botón se "presiona" cuando se presiona la tecla ENTER. No se cierra el cuadro de diálogo, y no establece el DialogResult, hay que hacerlo de forma manual en el código subyacente:

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

(ajuste de DialogResult también cierra la ventana)

+8

No muy consistente con IsCancel que establece DialogResult. Por cierto, establecer DialogResult es suficiente, configurarlo cierra la ventana. –

+0

@SoMoS, tienes razón, por supuesto. Eliminé la llamada para Cerrar. –

8

Para hacer las cosas más agradable , se puede utilizar una propiedad adjunta como éste:

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

la propiedad adjunta se puede definir como tal:

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