C# 如何更改资源模板元素';仅使用XAML的属性?

C# 如何更改资源模板元素';仅使用XAML的属性?,c#,wpf,xaml,C#,Wpf,Xaml,其主要思想是有一个带有默认图标“yes.png”的按钮和其中的文本“Accept”,但可以仅使用XAML更改这两个属性(在设计过程中,无需编译) 当前XAML窗口,底部有一个区域,只有两个按钮: <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Window.R

其主要思想是有一个带有默认图标
“yes.png”
的按钮和其中的文本
“Accept”
,但可以仅使用XAML更改这两个属性(在设计过程中,无需编译)

当前XAML窗口,底部有一个区域,只有两个按钮:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>
        <ResourceDictionary>
            <Style x:Key="tb1" TargetType="{x:Type Button}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Border BorderThickness="1" BorderBrush="#000" Padding="0">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition/>
                                    </Grid.ColumnDefinitions>
                                    <Image Source="Files/Icons/no.png" Margin="10,0,0,0" Height="16" Width="16"></Image>
                                    <TextBlock Grid.Column="1" Margin="10" VerticalAlignment="Center">Cancel</TextBlock>
                                </Grid>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Setter Property="Margin" Value="0,10,10,10"></Setter>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Border BorderThickness="0, 1, 0, 0" BorderBrush="#e7e7e7" HorizontalAlignment="Stretch" Padding="0,0,0,0" VerticalAlignment="Bottom" Height="61">
            <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
                <Button x:Name="b_Accept" Style="{StaticResource tb1}"></Button> <!-- How to change an icon to "yes.png" and TextBlock's content to "Accept"? -->
                <Button x:Name="b_Cancel" Style="{StaticResource tb1}"></Button>
            </StackPanel>
        </Border>
    </Grid>
</Window>

取消
结果:

  • 如何将第二个按钮的图标更改为
    “no.png”
    源属性),将文本块的文本(内容)更改为
    “取消”
    仅使用XAML不使用用户控件

  • 最正确的方法是什么?例如,在本例中,我们可能使用DataTemplate,但这可能不是我们想要的,因为DataTemplate更改了整个元素,而我们只需要一个属性

  • 尽管如此,我认为只有
    依赖性属性
    (C#)可用于需要编译的目的,这是对的


    谢谢

    您可以创建自定义的
    按钮
    类或附加属性来扩展
    按钮

    public class IconControl : DependencyObject
    {
      #region IconUri attached property
    
      public static readonly DependencyProperty IconUriProperty = DependencyProperty.RegisterAttached(
        "IconUri", typeof(ImageSource), typeof(IconControl), new PropertyMetadata(default(ImageSource)));
    
      public static void SetIconUri([NotNull] DependencyObject attachingElement, ImageSource value)
      {
        attachingElement.SetValue(IconControl.IconUriProperty, value);
      }
    
      public static ImageSource GetIconUri([NotNull] DependencyObject attachingElement) => (ImageSource) attachingElement.GetValue(IconControl.IconUriProperty);
    
      #endregion
    
      #region Label attached property
    
      public static readonly DependencyProperty LabelProperty = DependencyProperty.RegisterAttached(
        "Label", typeof(String), typeof(IconControl), new PropertyMetadata(default(String)));
    
      public static void SetLabel([NotNull] DependencyObject attachingElement, String value)
      {
        attachingElement.SetValue(IconControl.LabelProperty, value);
      }
    
      public static String GetLabel([NotNull] DependencyObject attachingElement) => (String) attachingElement.GetValue(IconControl.LabelProperty);
    
      #endregion
    }
    
    <Style x:Key="IconButtonStyle"
           TargetType="{x:Type Button}">
    
      <!-- Set the default values -->
      <Setter Property="IconControl.IconUri" Value="/Files/Icons/no.png"/>
      <Setter Property="IconControl.Label" Value="Cancel"/>
    
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
            <Border BorderThickness="1"
                    BorderBrush="#000"
                    Padding="0">
              <Grid>
                <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="Auto" />
                  <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(IconControl.IconUri)}"
                       Margin="10,0,0,0"
                       Height="16"
                       Width="16" />
                <TextBlock Grid.Column="1"
                           Margin="10"
                           VerticalAlignment="Center"
                           Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(IconControl.Label)}" />
              </Grid>
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
      <Setter Property="Margin"
              Value="0,10,10,10"></Setter>
    </Style>
    
    修改了
    按钮的
    样式

    public class IconControl : DependencyObject
    {
      #region IconUri attached property
    
      public static readonly DependencyProperty IconUriProperty = DependencyProperty.RegisterAttached(
        "IconUri", typeof(ImageSource), typeof(IconControl), new PropertyMetadata(default(ImageSource)));
    
      public static void SetIconUri([NotNull] DependencyObject attachingElement, ImageSource value)
      {
        attachingElement.SetValue(IconControl.IconUriProperty, value);
      }
    
      public static ImageSource GetIconUri([NotNull] DependencyObject attachingElement) => (ImageSource) attachingElement.GetValue(IconControl.IconUriProperty);
    
      #endregion
    
      #region Label attached property
    
      public static readonly DependencyProperty LabelProperty = DependencyProperty.RegisterAttached(
        "Label", typeof(String), typeof(IconControl), new PropertyMetadata(default(String)));
    
      public static void SetLabel([NotNull] DependencyObject attachingElement, String value)
      {
        attachingElement.SetValue(IconControl.LabelProperty, value);
      }
    
      public static String GetLabel([NotNull] DependencyObject attachingElement) => (String) attachingElement.GetValue(IconControl.LabelProperty);
    
      #endregion
    }
    
    <Style x:Key="IconButtonStyle"
           TargetType="{x:Type Button}">
    
      <!-- Set the default values -->
      <Setter Property="IconControl.IconUri" Value="/Files/Icons/no.png"/>
      <Setter Property="IconControl.Label" Value="Cancel"/>
    
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
            <Border BorderThickness="1"
                    BorderBrush="#000"
                    Padding="0">
              <Grid>
                <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="Auto" />
                  <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(IconControl.IconUri)}"
                       Margin="10,0,0,0"
                       Height="16"
                       Width="16" />
                <TextBlock Grid.Column="1"
                           Margin="10"
                           VerticalAlignment="Center"
                           Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(IconControl.Label)}" />
              </Grid>
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
      <Setter Property="Margin"
              Value="0,10,10,10"></Setter>
    </Style>
    
    
    
    用法:

    <!-- Override the default content -->
    <Button Style="{StaticResource IconButtonStyle}"
            IconControl.IconUri="/Files/Icons/yes.png"
            IconControl.Label="Accept" />
    
    
    
    这需要C#编译。是否可以不使用<代码>依赖性属性< /代码>?现在它说“在Windows演示基础(WPF)项目中不支持IconControl。”在XAML设计窗口中,您必须限定类型的命名空间,例如,“代码> MyMaSeStay:ICONCONNECULT.Label=“Access”< /代码>。这对于所有xaml对象都是典型的。您所说的“需要编译”是什么意思?无论是C#还是XAML,您都必须编译代码。Windows无法执行.xaml文件。根据C#编译的含义,它不会让在设计窗口中立即查看结果。按钮是一个contentcontrol。它已经有一个内容依赖属性,您可以使用它来更改其内容。您可以使用xaml通过datatemplate或datatrigger来实现这一点。我会在附加财产之前考虑这个办法。除非附加dp有其他原因。Wpf具有非常轻量级的组件,允许您使用基于矢量的图像,例如路径和几何图形。这些通常比基于位图的图片(如png)更可取。@Andy好的,所以可以更改“开箱即用”按钮的内容,但是内部元素呢?您可以在模板中使用内容控件,但我看不出有此需要。