微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何基于 MaterialDesign 构建自定义组件?

如何解决如何基于 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 控件或构建自定义控件并没有真正的区别。

对于自定义按钮内容的简单情况,创建您指定为 DataTemplateContentTemplateButton 可能是一种更简单的替代方法,请参阅{{3 }}。

,

当您设置控件模板时,它会覆盖所有视觉样式。它仅携带依赖属性。因此,它不会带有任何阴影或其他效果(至少对于您的新风格而言)。但是,如果此类属性存在于 VerticalButton 类(您的目标)中,那么您可以重用此类属性并定义您自己的样式。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。