Jon*_*lis 6 c# wpf user-interface styles controltemplates
我正在尝试学习WPF,并试图通过使用样式使默认的.Net控件看起来不同.使用C#作为我的首选语言,尽管下面的所有代码都是WPF标记.
我今天用新主题设置了gmail(见下图),从而让我自己成为挑战,可以在WPF中完成.

我设法实现的是Spam通过使用带有控件模板和触发器的样式来创建中间按钮.
右侧和左侧按钮非常相似,但只有2个不同.它们的左侧或右侧的圆角半径为1,边距为15,而中间的按钮则将它们都设置为0.
问题!
Q1.可以通过某种类型的继承来完成,而不是复制整个样式并仅更改这两个属性.右侧和左侧按钮的位置基于现有样式,但它会进行2次视觉更改.我在创建新样式时已尝试过BasedOn属性,但无法编辑所需的属性.
Q2.样式是在WPF中解决此问题的正确方法.在WinForms中,您将创建一个自定义控件,该控件具有链接到枚举的可见属性,即您单击按钮,样式选项可能是Left,Middle,Right.
Q3.最难的问题直到最后.是否可以制作它,所以如果一个按钮应用了我的风格.然后当您将其背景颜色设置为蓝色时.然后按钮保持渐变但不是它们是灰白色,而是现在是蓝色的阴影.即背景线性渐变画笔基于,而不是覆盖已应用于按钮的背景颜色.或者这些需要定义单独的样式.我个人看不到没有某种类型的代码可以实现这一点,即在WPF标记中使用单个画笔制作渐变画笔.
即按钮如下方的蓝色按钮和灰色/普通按钮

我的风格
<Style x:Key="GoogleMiddleButton" TargetType="{x:Type Button}">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
<GradientStop Color="#F1F1F1" Offset="0"/>
<GradientStop Color="#F5F5F5" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="#666666"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="dropShadowBorder"
BorderThickness="0,0,0,1"
CornerRadius="1"
>
<Border.BorderBrush>
<SolidColorBrush Color="#00000000"/>
</Border.BorderBrush>
<Border Name="border"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
CornerRadius="0"
Background="{TemplateBinding Background}">
<Border.BorderBrush>
<SolidColorBrush Color="#D8D8D8"/>
</Border.BorderBrush>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="border">
<Setter.Value>
<SolidColorBrush Color="#939393"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" TargetName="dropShadowBorder">
<Setter.Value>
<SolidColorBrush Color="#EBEBEB"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#333333"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
<GradientStop Color="#F1F1F1" Offset="1"/>
<GradientStop Color="#F5F5F5" Offset="0"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
Run Code Online (Sandbox Code Playgroud)
ps如果您发现上面WPF中的任何初学者错误,请随时向我指出.
我过去通过定义一个名为的附加属性来完成此操作ExtendedProperties.CornerRadius.然后我可以按照我的风格设置它:
<Style TargetType="Button">
<Setter Property="local:ExtendedProperties.CornerRadius" Value="0"/>
...
Run Code Online (Sandbox Code Playgroud)
并在模板中使用它:
<Border CornerRadius="{Binding Path=(local:ExtendedProperties.CornerRadius), RelativeSource={RelativeSource TemplatedParent}">
Run Code Online (Sandbox Code Playgroud)
然后我可以在本地覆盖它,就像我覆盖任何其他属性一样:
<Button Content="Archive" local:ExtendedProperties.CornerRadius="5,0,0,5"/>
<Button Content="Span"/>
<Button Content="Delete" local:ExtendedProperties.CornerRadius="0,5,5,0"/>
Run Code Online (Sandbox Code Playgroud)
就我而言,这给了我(显然,我的主题是黑暗的):

只是通过调整我的几个主题的附加属性,我创建了这个效果:

这种方法的优点是不需要子类Button.您还可以使用相同的附加属性为其他控件(例如TextBox)定义角半径.当然,你并不仅限于角落半径.您可以为基本控件上不存在的主题特定的各种事物定义附加属性.
缺点是它是附属物,因此更难发现.记录您的主题将有助于这方面.
那么,回答你的具体问题:
Q1.是的,请参阅上面的答案.您可以在本地覆盖或定义覆盖该属性的新样式.
Q2.这是一个灰色地带.在我看来,如果它纯粹是视觉(不是行为),那么风格就是你要走的路.当然,如果失控,您可能希望继承所有内置控件并添加您的特定属性.但这会使您的主题更难以重复使用,并且您的应用程序更难以开发(因为您需要使用您的控件集而不是标准控件集).
Q3.我说它可以在代码中使用,但不能直观地用作控件使用者.我认为你最好定义额外的附加属性 - 例如.ExtendedProperties.HoverBackground,ExtendedProperties.PressedBackground- 以完全相同的方式使用模板中的那些.然后,当您的控件处于各种状态时,您的控件的使用者可以更好地控制所使用的画笔.我以前做过这个,但是使用了更多的通用属性名称(SecondaryBackground,TernaryBackground),所以我可以在其他上下文中重用这些属性.再次,记录您的主题是有帮助的.
| 归档时间: |
|
| 查看次数: |
4750 次 |
| 最近记录: |