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

问题描述:

我曾尝试过谷歌,但我并不是非常清楚我看到的人们提出的建议。 我有一个用户控件中的3个按钮,除了自动识别和文本以外完全一样。我想创建一个可以使用的通用控件或控件模板,而不是在所有按钮上重复此代码。我的问题是这些按钮有嵌套控件的文本,我需要改变,但我不知道如何做到这一点。如何使用xaml中的常用模板/控件创建可重用控件并设置嵌套控件的属性

<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="[email protected]" 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和文本属性。

谢谢!

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

如果您想对它们使用绑定或动画,强烈建议使用依赖属性而不是简单属性。

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"/> 
+0

我错过了ElementName部分。感谢你和卡夫斯! – user1192724

它可能比你想做的更多的工作,但它听起来像你要创建一个UserControl。它应该从按钮的代码隐藏继承:

public partial class MyButton: Button 

在XAML,你将主要包括你现在在每个按钮什么的胆量。 (在代码隐藏中)需要为每个要在此控件中设置的“属性”创建一个DependencyProperty:例如,一个用于CallIconAutomationId,一个用于CallLabelAutomationId,一个用于CallLabelText等。然后,您将将XAML中的每个属性都绑定到依赖项属性。这些属性成为您将在每个单独的MyButton(您的新UserControl)上设置的数据。

然后,在承载这些控件(这似乎是在你上面的例子另一个用户控件),你会在每个新myButton的控件设置这些自定义属性,这将是这个样子的容器:

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

基本上,你创建一个基于Button控件新控件(用户控件)(它为您提供了大部分的功能),并直接添加新的自定义属性,以新的控制(这工作就像您习惯的其他所有控制属性一样)。

+0

谢谢!这清楚地解释了我需要做的事情。绑定虽然不能正常工作。我把一个断点,我看到该属性正在设置,但它运行时不显示文本。有任何想法吗?将更新问题 – user1192724

+0

是的,请显示绑定,他们应该很简单。 – karfus