-1

我有以下 WPF 控件,用于显示旁边带有图像的文本

XAML 代码

<UserControl x:Class="WFWorkSpaceWPF.UserControls.StackedImageTextCtl"
         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" 
         mc:Ignorable="d" 
         Name="StackedImageText"
         >
<Grid>
    <StackPanel Orientation="Horizontal">
        <Image Source="{Binding ElementName=StackedImageText, Path=ImageSource}" />
        <TextBlock Text="{Binding ElementName=StackedImageText, Path=Text}" />
    </StackPanel>
</Grid>

CS

 public partial class StackedImageTextCtl : UserControl
{
    public StackedImageTextCtl()
    {
        InitializeComponent();
    }
    #region "Properties"
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
      DependencyProperty.Register("Text", typeof(string), typeof(StackedImageTextCtl), new UIPropertyMetadata(""));

    public ImageSource ImageSource
    {
        get { return (ImageSource)GetValue(ImageSourceProperty); }
        set { SetValue(ImageSourceProperty, value); }
    }

    public static readonly DependencyProperty ImageSourceProperty =
       DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(StackedImageTextCtl), new UIPropertyMetadata(null));
    #endregion
}

在我的项目中,我想在其他三个用户控件中重用此控件,它将作为这些控件的一部分添加,正如您所见,StackedImageTextCtl 公开了父用户控件需要提供的两个属性(文本和图像源)它和这三个控件将从容器窗口中获取值 throw XAML,我知道这样做的一种方法是复制定义这三个用户控件中的每一个中的属性并使用 AddOwner 功能,但我正在寻找一个更好的方法,不需要任何重复代码,有人可以指导我这样做吗?

4

1 回答 1

1

这是您的用户控件:

<UserControl ...>
    <StackPanel Orientation="Horizontal">
        <Image Source="{Binding ImageSource}" Width="16"/>
        <TextBlock Text="{Binding Text}" />
    </StackPanel>
</UserControl>

及其代码:

除了Textand之外ImageSource,还有Statewhich 表示Add/Edit/delete该控件的状态,还有StackCtlStatewhich 是附加属性,当附加到 a 时,FrameworkElement它表示该Add/Edit/delete控件的状态。

    public StackedImageTextCtl()
    {
        InitializeComponent();
        DataContext = this;
    }
    //Text Dependency Property
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(StackedImageTextCtl), new UIPropertyMetadata(null));
    //ImageSource Dependency Property
    public ImageSource ImageSource
    {
        get { return (ImageSource)GetValue(ImageSourceProperty); }
        set { SetValue(ImageSourceProperty, value); }
    }
    public static readonly DependencyProperty ImageSourceProperty =
        DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(StackedImageTextCtl), new UIPropertyMetadata(null));
    //State Dependency Property
    public AddEditDelete State
    {
        get { return (AddEditDelete)GetValue(StateProperty); }
        set { SetValue(StateProperty, value); }
    }
    public static readonly DependencyProperty StateProperty =
        DependencyProperty.Register("State", typeof(AddEditDelete), typeof(StackedImageTextCtl), new UIPropertyMetadata(AddEditDelete.Add));

    public static AddEditDelete GetStackCtlState(DependencyObject obj)
    {
        return (AddEditDelete)obj.GetValue(StackCtlStateProperty);
    }

    public static void SetStackCtlState(DependencyObject obj, AddEditDelete value)
    {
        obj.SetValue(StackCtlStateProperty, value);
    }
    public static readonly DependencyProperty StackCtlStateProperty =
        DependencyProperty.RegisterAttached("StackCtlState", typeof(AddEditDelete), typeof(StackedImageTextCtl), new UIPropertyMetadata(AddEditDelete.Add));

我还定义了一个枚举:

public enum AddEditDelete { Add, Edit, Delete }

在窗口 xaml 中:

每个ButtonorToggleButton将其附加属性StackCtlState设置为所需的值,并将其样式设置为Buttonor的样式之一ToggleButton

然后这些样式StackedImageTextCtl以正确的方式添加到样式按钮/切换按钮的内容中,以便可以重用资源。(如果您只设置 Content 而没有设置 Template ,它只会显示 lastButton或 last的内容ToggleButton)添加StackedImageTextCtlState值等于其附加值,TemplatedParentButtonor ToggleButton

最后,样式用于设置 Text 和 Image 的值,Trigger基于State.StackedImageTextCtl

<Window...
     xmlns:myNamespace="clr-namespace:WpfApplication1">


<Window.Resources>
    <Style TargetType="{x:Type myNamespace:StackedImageTextCtl}">
        <Style.Triggers>
            <Trigger Property="State" Value="Add">
                <Setter Property="Text" Value="ADD"/>
                <Setter Property="ImageSource" Value="/blue_1.jpg"/>
            </Trigger>
            <Trigger Property="State" Value="Edit">
                <Setter Property="Text" Value="EDIT"/>
                <Setter Property="ImageSource" Value="/blue_2.jpg"/>
            </Trigger>
            <Trigger Property="State" Value="Delete">
                <Setter Property="Text" Value="DELETE"/>
                <Setter Property="ImageSource" Value="/blue_3.jpg"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="stackButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Button>
                        <myNamespace:StackedImageTextCtl State="{TemplateBinding myNamespace:StackedImageTextCtl.StackCtlState}"/>
                    </Button>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="stackToggleButtonStyle" TargetType="{x:Type ToggleButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <ToggleButton>
                        <myNamespace:StackedImageTextCtl State="{TemplateBinding myNamespace:StackedImageTextCtl.StackCtlState}"/>
                    </ToggleButton>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<StackPanel>
    <Button Style="{StaticResource stackButtonStyle}" myNamespace:StackedImageTextCtl.StackCtlState="Add"/>
    <Button Style="{StaticResource stackButtonStyle}" myNamespace:StackedImageTextCtl.StackCtlState="Edit"/>
    <ToggleButton Style="{StaticResource stackToggleButtonStyle}" myNamespace:StackedImageTextCtl.StackCtlState="Delete"/>
</StackPanel>
于 2013-11-10T17:10:48.187 回答