【问题标题】:Wpf - Default Button not Working as ExpectedWpf - 默认按钮未按预期工作
【发布时间】:2010-12-30 19:34:02
【问题描述】:

我在下面的 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 按钮或关闭窗口时。

给不知情的人的建议?

【问题讨论】:

    标签: wpf button


    【解决方案1】:

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

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

    (设置DialogResult也会关闭窗口)

    【讨论】:

    • 与设置DialogResult的IsCancel不太一致。对了,设置DialogResult就够了,设置它关闭窗口。
    【解决方案2】:

    为了让事情变得更好,您可以使用这样的附加属性:

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

    【讨论】:

      猜你喜欢
      • 2016-07-01
      • 2014-08-20
      • 1970-01-01
      • 2013-01-21
      • 2021-04-06
      • 2019-01-06
      • 2011-05-20
      • 2010-09-19
      • 2013-07-19
      相关资源
      最近更新 更多