如何解决如何基于 MaterialDesign 构建自定义组件?
我试图了解如何基于 Material Design 构建自定义组件,以了解实现这一目标的过程究竟是如何工作的,我想构建一个包含文本和图标的简单按钮(记住只是练习),所以我尝试同时写一个 UserControl
和一个 ResurceDictionary
,但到目前为止没有运气。我的问题是,如何基于材料设计构建自定义按钮?我希望它保持 Material Design 附带的所有效果和阴影。我也会发布我在 ResurceDictionary
方面的内容。
资源字典
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:KESS3Mockup">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style targettype="{x:Type local:VerticalButton}" BasedOn="{StaticResource ResourceKey={x:Type Button}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate targettype="{x:Type local:VerticalButton}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="2"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDeFinitions>
<RowDeFinition Height="0.5*"/>
<RowDeFinition Height="8*"/>
<RowDeFinition Height="8*"/>
<RowDeFinition Height="0.5*"/>
</Grid.RowDeFinitions>
<Grid.ColumnDeFinitions>
<ColumnDeFinition Width="1*"/>
<ColumnDeFinition Width="20*"/>
<ColumnDeFinition Width="1*"/>
</Grid.ColumnDeFinitions>
<ViewBox HorizontalAlignment="Stretch" Grid.Column="1" Grid.Row="1">
<materialDesign:PackIcon Kind="{TemplateBinding Kind}" Foreground="White" />
</ViewBox>
<ViewBox Grid.Column="1" Grid.Row="2">
<TextBox Text="{TemplateBinding Text}" Foreground="White" SelectionBrush="#000078D7" BorderBrush="#00000000" Focusable="False"/>
</ViewBox>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
解决方法
您可以使用 BasedOn
在现有样式的基础上创建新样式。
<Style TargetType="{x:Type local:VerticalButton}" BasedOn="{StaticResource {x:Type Button}}">
除了类型之外,您还可以引用不同的特定样式。
<Style TargetType="{x:Type local:VerticalButton}" BasedOn="{StaticResource MaterialDesignFlatButton}"/>
但是,要使其工作,目标类型必须兼容(相同类型或基类型,例如 ButtonBase
表示 Button
)。您不能简单地创建 UserControl
并根据 Button
的样式创建样式。为了自定义 Button
,您必须创建一个继承自 VerticalButton
的自定义控件 Button
,它实现了您想要的依赖属性和细节。
public class VerticalButton : Button
{
static VerticalButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(VerticalButton),new FrameworkPropertyMetadata(typeof(VerticalButton)));
}
// ...your custom code.
}
接下来,您将在项目的 Generic.xaml
文件夹中创建一个 Themes
文件(此路径和文件按惯例命名)。您可以在此处定义默认样式,该样式可以基于 Material Design。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:YourProject">
<Style TargetType="{x:Type local:VerticalButton}" BasedOn="{StaticResource {x:Type Button}}">
<!-- ...your style definitions. -->
</Style>
</ResourceDictionary>
此资源词典必须包含在 App.xaml
中的 Material Design 主题词典之后。有关如何覆盖默认 Material Design 主题的更多信息,您可以refer to the Wiki。
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
请注意,虽然您可以将样式建立在另一种样式的基础上,但您不能将一个控件模板建立在另一个之上。这意味着,如果您在样式中分配 ControlTemplate
,它将覆盖基本样式之一。因此,如果您想调整控件模板,同时保留其大部分默认视觉效果和效果,您必须copy it from the Material Design GitHub repository 并根据您的需要进行调整。
有关开发自定义控件的更多信息,请参阅Control authoring overview。 Material Design 使用既定的主题、样式和模板概念,因此它与样式标准 WPF 控件或构建自定义控件并没有真正的区别。
对于自定义按钮内容的简单情况,创建您指定为 DataTemplate
的 ContentTemplate
的 Button
可能是一种更简单的替代方法,请参阅{{3 }}。
当您设置控件模板时,它会覆盖所有视觉样式。它仅携带依赖属性。因此,它不会带有任何阴影或其他效果(至少对于您的新风格而言)。但是,如果此类属性存在于 VerticalButton 类(您的目标)中,那么您可以重用此类属性并定义您自己的样式。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。