【问题标题】:Only apply style to non-nested controls in WPF仅将样式应用于 WPF 中的非嵌套控件
【发布时间】:2015-11-17 06:31:08
【问题描述】:

在 WPF 中,我对某些控件的默认样式不满意,例如 <Button />,默认情况下它与本机 Win32 按钮的尺寸不同。幸运的是,通过应用 MinWidth 和 Margin 属性很容易解决。

我没有手动将这些属性应用于 XAML 中的每个 <Button />,而是将它们设置为我的 App.xaml 文件的 ResourceDictionary 中的样式,如下所示:

<Style TargetType="Button">
    <Setter Property="Margin" Value="4" />
    <Setter Property="MinWidth" Value="73" />
</Style>

但是,这意味着 UI 中的所有按钮现在都具有这种样式,例如嵌套在 &lt;DatePicker /&gt; 甚至 &lt;MenuItem /&gt; 中的按钮,使 UI 变得更糟。

我知道我可以将x:Key="b" 添加到&lt;Style /&gt;,然后将我的XAML 更改为&lt;Button Style={StaticResource b} /&gt;,但这看起来就像在每个控件实例上手动设置属性一样麻烦。

有没有办法只将样式应用到 my 控件而不是嵌套在其他 UI 组件中的控件?即我希望我自己的 XAML 中的所有 &lt;Button /&gt; 实例具有相同的样式,但不是内置 WPF 控件或任何第三方库中的按钮。

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    您可以制作自己的按钮类型并在其上应用样式:

    public class MyButton: Button {}
    
    ...
    
    <Style TargetType="yourNamespace:MyButton">
        <Setter Property="Margin" Value="4" />
        <Setter Property="MinWidth" Value="73" />
    </Style>
    

    【讨论】:

    • 问题是,我发现自己需要在几乎每个内置 WPF 控件上设置样式(边距、填充、尺寸等)。那时我将不得不对几乎每个 WPF 控件进行子类化。它只是不“看起来正确”>
    • 另外,有没有办法让样式只适用于另一个控件的子元素? (例如“仅样式 &lt;Button&gt;&lt;Border /&gt; 的直接子代的实例)?
    • @Dai - 如果您在边框的资源中包含样式,那么它将仅适用于孩子。
    • @user3690202 假设您的 Borders 是 Border 的子项。以 Border 为目标的样式不会影响父级和子级吗?
    • @KyleDelaney 可能,但这就是他想要的或暗示他想要的。 TBH,这条评论已经有几年历史了,我不再做太多 WPF 了——我觉得它是一种垂死的技术,甚至连 MS 都拒绝了。它非常强大和灵活,但它几乎是无法学习的复杂,尤其是在这种情况下。这些天来,我更多地使用 WinForms 控件,只是因为考虑到性能,它们更容易编写。
    【解决方案2】:

    您可以从Button 派生并使用自定义的MarginMinWidth 值创建自己的类型。

    无需为此创建单独的样式,甚至无需创建新的 .xaml 控件,只需一个继承的类即可。

    public class MyButton: Button 
    {
        public MyButton()
        {
            Margin = new Thickness(4);
            MinWidth = 73;
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果您只想定位特定按钮,则无法使用 x:Key。明确地设置按钮的样式并没有错,但是有一些技巧可以让您使用 x:Key 有选择地对样式进行分组。

      首先,使用 app.xaml 中的键创建您的样式:

      <Style TargetType="Button" x:Key="MyButtonStyle">
          <Setter Property="Margin" Value="4"/>
          <Setter Property="MinWidth" Value="73"/>
      </Style>
      

      将样式 BasedOn 应用到按钮的父容器

      <DockPanel>
          <StackPanel>
              <!--Apply your button style to contents of StackPanel-->
              <StackPanel.Resources>
                  <Style TargetType="Button" BasedOn="{StaticResource MyButtonStyle}">
                      <!--You can add extra setters to the style without affecting the original-->
                      <Setter Property="ToolTip" Value="This is my button"/>
                  </Style>
              </StackPanel.Resources>
      
              <Button Content="Test1"/>
              <Button Content="Test2"/>
              <Button Content="Test3"/>
              <Button Content="Test4"/>
          </StackPanel>
      
          <!--Buttons built into DatePicker are unaffected-->
          <DatePicker/>
      </DockPanel>
      

      另外仅供参考,您的样式不一定需要存在于 app.xaml 中。

      <DockPanel>
          <StackPanel>
              <!--Apply your button style to contents of StackPanel-->
              <StackPanel.Resources>
                  <Style TargetType="Button">
                      <Setter Property="Margin" Value="4"/>
                      <Setter Property="MinWidth" Value="73"/>
                  </Style>
              </StackPanel.Resources>
      
              <Button Content="Test1"/>
              <Button Content="Test2"/>
              <Button Content="Test3"/>
              <Button Content="Test4"/>
          </StackPanel>
      
          <!--Buttons built into DatePicker are unaffected-->
          <DatePicker/>
      </DockPanel>
      

      【讨论】:

        猜你喜欢
        • 2020-04-17
        • 2011-06-08
        • 2016-09-18
        • 2021-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多