繁体   English   中英

WPF 按钮作为带有文本和矢量图标的自定义控件

[英]WPF button as custom control with text and vector icon

各位晚安,

我真的很想有一个带有文本和矢量图标的自定义按钮..我搜索了类似的东西但没有运气..所以我自己尝试制作自定义控件但我无法使其工作:没有错误或发现警告,但图标根本不出现。 在我的代码下面:

自定义控件 CS:

 public class ThButton : Button
{
    static ThButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ThButton), new FrameworkPropertyMetadata(typeof(ThButton)));
    }

    public static readonly DependencyProperty IconProperty =
        DependencyProperty.Register("Icon", typeof(Path), typeof(ThButton), new UIPropertyMetadata(null));

    public Path Icon
    {
        get { return (Path)GetValue(IconProperty); }
        set { SetValue(IconProperty, value); }
    }

    public static readonly DependencyProperty ThLabelProperty =
        DependencyProperty.Register("ThLabel", typeof(string), typeof(ThButton), new UIPropertyMetadata(null));

    public String ThLabel
    {
        get { return (String)GetValue(ThLabelProperty); }
        set { SetValue(ThLabelProperty, value); }
    }

}

generic.xaml (触发器等已删除,因为对此无用):

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:CustomControlTest">

    <Path x:Key="BoatIcon" Fill="Black" Data="M6,6H18V9.96L12,8L6,9.96M3.94,19H4C5.6,19 7,18.12 8,17C9,18.12 10.4,19 12,19C13.6,19 15,18.12 16,17C17,18.12 18.4,19 20,19H20.05L21.95,12.31C22.03,12.06 22,11.78 21.89,11.54C21.76,11.3 21.55,11.12 21.29,11.04L20,10.62V6C20,4.89 19.1,4 18,4H15V1H9V4H6A2,2 0 0,0 4,6V10.62L2.71,11.04C2.45,11.12 2.24,11.3 2.11,11.54C2,11.78 1.97,12.06 2.05,12.31M20,21C18.61,21 17.22,20.53 16,19.67C13.56,21.38 10.44,21.38 8,19.67C6.78,20.53 5.39,21 4,21H2V23H4C5.37,23 6.74,22.65 8,22C10.5,23.3 13.5,23.3 16,22C17.26,22.65 18.62,23 20,23H22V21H20Z" />

    <Color x:Key="BackgroundColor1" A="255" R="0" G="133" B="209"/>
    <Color x:Key="BackgroundColor2" A="255" R="0" G="61" B="94"/>

    <Color x:Key="MouseOverBackgroundColor1" A="255" R="0" G="156" B="231"/>
    <Color x:Key="MouseOverBackgroundColor2" A="255" R="0" G="90" B="155"/>

    <Color x:Key="MousePressedBackgroundColor1" A="255" R="0" G="98" B="195"/>
    <Color x:Key="MousePressedBackgroundColor2" A="255" R="0" G="36" B="72"/>

    <Color x:Key="IsNotEnabledBackgroundColor1" A="255" R="233" G="233" B="233"/>
    <Color x:Key="IsNotEnabledBackgroundColor2" A="255" R="240" G="240" B="240"/>

    <SolidColorBrush x:Key="ThBorderBrush" Color="#ECECEC"></SolidColorBrush>

    <Style TargetType="{x:Type local:ThButton}">
        <Setter Property="BorderBrush" Value="{StaticResource ThBorderBrush}"/>
        <Setter Property="BorderThickness" Value="2"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ThButton}">
                    <Border x:Name="t"
                            Margin="{TemplateBinding Margin}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            CornerRadius="6">

                        <Border.Background>
                            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                <LinearGradientBrush.GradientStops>
                                    <GradientStop x:Name="BackgroundGradientStop1" Offset="0" Color="{StaticResource BackgroundColor1}"/>
                                    <GradientStop x:Name="BackgroundGradientStop2" Offset="1" Color="{StaticResource BackgroundColor2}"/>
                                </LinearGradientBrush.GradientStops>
                            </LinearGradientBrush>
                        </Border.Background>

                        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
                            <Rectangle Width="20" Height="20" Fill="black" Margin="0,0,0,5">
                                <Rectangle.OpacityMask>
                                    <VisualBrush Stretch="Fill" Visual="{TemplateBinding Icon}"/>
                                </Rectangle.OpacityMask>
                            </Rectangle>
                            <Label Content="{TemplateBinding ThLabel}"/>
                        </StackPanel>

                    </Border>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

最后是 mainWindow.xaml:

<local:ThButton Width="100" Icon="{StaticResource BoatIcon}" ThLabel="Test"/>

如果我在 Visual (generic.xaml) 中将“{StaticResource BoatIcon}”代替“{TemplateBinding Icon}”,则会出现图标,所以我想问题在于我如何尝试使用 DependencyProperty。

这可以很容易地使用自定义UserControl来完成。

首先,将您的图像添加到您的项目资源中,并在属性中设置“构建类型 = 资源”。 通过选择新添加的图像并右键单击,然后设置上述属性来执行此操作。

接下来,创建一个UserControl 这是我的XAML

<UserControl x:Class="ListViewDragAndDrop.UCPictureButton"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ListViewDragAndDrop"
             mc:Ignorable="d" 
             d:DesignHeight="32" d:DesignWidth="128">
    <Grid>
        <Button Click="Button_Click">
            <StackPanel Orientation="Horizontal">
                <Image Source="/Resources/solution.png"
                       Margin="4, 4, 8, 4"/>
                <TextBlock Text="Button Text"
                           HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </StackPanel>
        </Button>  
    </Grid>
</UserControl>

确保图像的“来源”正确。 上面显示的是它在我的项目中的默认位置。

然后后面的UserControl代码:

public partial class UCPictureButton : UserControl
{
    public event RoutedEventHandler RoutedButtonClick;

    public UCPictureButton()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        RoutedButtonClick?.Invoke(this, e);
    }
}

在按钮单击事件中,我们调用我们在此处声明的RoutedEvent

现在在您的Main window 或您想使用按钮的任何地方:

<local:UCPictureButton Grid.Column="2" Width="120" Height="32">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="RoutedButtonClick">
            <i:InvokeCommandAction Command="{Binding CmdButtonClick}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</local:UCPictureButton>

i命名空间是interactivity命名空间:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

现在您所要做的就是在您的ViewModel中简单地将一个方法连接到上面声明的CmdButtonClick命令。

我正在使用MVVM Light工具包,它看起来像这样:

public RelayCommand CmdButtonClick { get; private set; }

public MainViewModel(IDataService dataService)
{
    CmdButtonClick = new RelayCommand(ButtonClick);
}

private void ButtonClick()
{
    // Button action
}

结果:

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM