如何在xaml中使用通用模板/控件创建可重用控件并设置嵌套控件的属性

本文关键字:控件 创建 设置 属性 嵌套 xaml | 更新日期: 2023-09-27 17:53:03

我试过谷歌这个,但我不是很清楚我看到人们提出的建议。我有一个用户控件中的3个按钮是完全相同的,除了自动化id和文本。我不想在所有按钮上重复这些代码,而是想创建一个我可以使用的公共控件或控件模板。我的问题是这些按钮有嵌套的控件,其文本我需要改变,但我不知道如何做到这一点。

<UserControl>
<Grid>       
        <StackPanel x:Name="myStackPanel" Grid.Row="1" Padding="0">
            <Button AutomationProperties.AutomationId="CallButton" x:Name="CallButton" Style="{StaticResource ButtonStyle}">
                <RelativePanel>
                    <SymbolIcon AutomationProperties.AutomationId="CallIcon" x:Name="CallIcon" Symbol="Phone" Style="{StaticResource SymbolStyle}" />
                    <StackPanel>
                        <TextBlock AutomationProperties.AutomationId="CallLabel" Text="Call" Style="{StaticResource LabelStyle}"/>
                        <TextBlock AutomationProperties.AutomationId="CallText" Text="123-456-7890" Style="{StaticResource ContentStyle}"/>
                    </StackPanel>
                </RelativePanel>
            </Button>
            <Button AutomationProperties.AutomationId="EmailButton" x:Name="EmailButton" Style="{StaticResource ButtonStyle}">
                <RelativePanel>
                    <SymbolIcon AutomationProperties.AutomationId="EmailIcon" x:Name="EmailIcon" Symbol="Mail" Style="{StaticResource SymbolStyle}"/>
                    <StackPanel >
                        <TextBlock AutomationProperties.AutomationId="EmailLabel" Text="Email" Style="{StaticResource LabelStyle}"/>
                        <TextBlock AutomationProperties.AutomationId="EmailText" Text="meetme@email.com" Style="{StaticResource ContentStyle}"/>
                    </StackPanel>
                </RelativePanel>
            </Button>
            <Button AutomationProperties.AutomationId="WebsiteButton" x:Name="WebsiteButton" Style="{StaticResource ButtonStyle}">
                <RelativePanel>
                    <SymbolIcon AutomationProperties.AutomationId="WebsiteIcon" x:Name="WebsiteIcon" Symbol="Link" Style="{StaticResource SymbolStyle}"/>
                    <StackPanel >
                        <TextBlock AutomationProperties.AutomationId="WebsiteLabel" Text="Website" Style="{StaticResource LabelStyle}"/>
                        <TextBlock AutomationProperties.AutomationId="WebsiteText" Text="http://meetme.com" Style="{StaticResource ContentStyle}"/>
                    </StackPanel>
                </RelativePanel>
            </Button>
        </StackPanel>          
    </Grid>
</Grid>

正如您所看到的,所有3个按钮的代码是相同的。我所要做的就是创建一个控件,我可以在其中设置嵌套控件的自动化id和文本属性。

谢谢!

如何在xaml中使用通用模板/控件创建可重用控件并设置嵌套控件的属性

您可以基于UserControl创建一个按钮(添加一个新的UserControl)。它将允许您享受所有的默认按钮的属性,事件和状态(OnClick,命令等),并添加自己的属性,模板和行为。

如果你想在依赖属性上使用绑定或动画,强烈建议使用依赖属性而不是简单属性。

c#

:

public partial class CustomButton : Button
{
    #region IconAutomationId
    public string IconAutomationId
    {
        get { return (string)GetValue(IconAutomationIdProperty); }
        set { SetValue(IconAutomationIdProperty, value); }
    }
    public static readonly DependencyProperty IconAutomationIdProperty =
        DependencyProperty.Register("IconAutomationId", typeof(string), typeof(CustomButton), new PropertyMetadata(null));
    #endregion
    #region LabelAutomationId
    public string LabelAutomationId
    {
        get { return (string)GetValue(LabelAutomationIdProperty); }
        set { SetValue(LabelAutomationIdProperty, value); }
    }
    public static readonly DependencyProperty LabelAutomationIdProperty =
        DependencyProperty.Register("LabelAutomationId", typeof(string), typeof(CustomButton), new PropertyMetadata(null));
    #endregion
    #region TextAutomationId
    public string TextAutomationId
    {
        get { return (string)GetValue(TextAutomationIdProperty); }
        set { SetValue(TextAutomationIdProperty, value); }
    }
    public static readonly DependencyProperty TextAutomationIdProperty =
        DependencyProperty.Register("TextAutomationId", typeof(string), typeof(CustomButton), new PropertyMetadata(null));
    #endregion
    #region Symbol
    public object Symbol
    {
        get { return (object)GetValue(SymbolProperty); }
        set { SetValue(SymbolProperty, value); }
    }
    public static readonly DependencyProperty SymbolProperty =
        DependencyProperty.Register("Symbol", typeof(object), typeof(CustomButton), new PropertyMetadata(null));
    #endregion
    #region Label
    public string Label
    {
        get { return (string)GetValue(LabelProperty); }
        set { SetValue(LabelProperty, value); }
    }
    public static readonly DependencyProperty LabelProperty =
        DependencyProperty.Register("Label", typeof(string), typeof(CustomButton), new PropertyMetadata(null));
    #endregion
    #region Text
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(CustomButton), new PropertyMetadata(null));
    #endregion
    public CustomButton()
    {
        InitializeComponent();
    }
}

XAML:

<Button x:Class="WpfApplication1.CustomButton"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="customButton">
    <RelativePanel>
        <SymbolIcon AutomationProperties.AutomationId="{Binding IconAutomationId, ElementName=customButton}"
                    Symbol="{Binding Symbol, ElementName=customButton}"
                    Style="{StaticResource SymbolStyle}"/>
        <StackPanel >
            <TextBlock AutomationProperties.AutomationId="{Binding LabelAutomationId, ElementName=customButton}"
                       Text="{Binding Label, ElementName=customButton}"
                       Style="{StaticResource LabelStyle}"/>
            <TextBlock AutomationProperties.AutomationId="{Binding TextAutomationId, ElementName=customButton}"
                       Text="{Binding Text, ElementName=customButton}"
                       Style="{StaticResource ContentStyle}"/>
        </StackPanel>
    </RelativePanel>
</Button>

使用:

<local:CustomButton AutomationProperties.AutomationId="CallButton"
                    x:Name="CallButton"
                    Style="{StaticResource ButtonStyle}"
                    IconAutomationId="CallIcon"
                    LabelAutomationId="CallLabel"
                    TextAutomationId="CallText"
                    Symbol="Phone"
                    Label="Call"
                    Text="123-456-7890"/>

这可能比你想做的要多,但听起来你想要创建一个UserControl。它应该继承自代码后面的Button:

public partial class MyButton: Button

在XAML中,您将包含现在每个按钮的基本内容。

繁琐的部分是,你将(在代码后面)需要为你想要在这个控件中设置的每个"属性"创建一个DependencyProperty:例如,一个用于CallIconAutomationId,一个用于CallLabelAutomationId,一个用于CallLabelText,等等。然后将XAML中的每个属性绑定到依赖项属性。这些属性将成为您将在每个MyButton(您的新UserControl)上设置的数据。

然后,在承载这些控件的容器中(在上面的例子中似乎是另一个UserControl),您将在每个新的MyButton控件上设置这些自定义属性,它们看起来像这样:

<myNamespace:MyButton EmailIconAutomationId="EmailIcon" LabelAutomationId="EmailLabel" />

等。

基本上,你是基于Button控件(它给了你大部分的功能)创建一个新的控件(UserControl),并直接向这个新控件添加新的自定义属性(它就像你习惯的所有其他控件属性一样工作)。