将用户控件转换为自定义控件

3
下面的UserControl工作得很好,但我希望更容易地改变样式。
我尝试过一件事情,就是将其转换为自定义控件,但我卡在了基础知识上,例如如何在处理属性更改的静态方法中设置ToolTip(见下文)。
我尝试的另一件事情是将样式移动到ResourceDictionary中的通用按钮样式,但这是本问题的主题。
如何在我的子类化Button中设置ToolTip?
干杯
<UserControl.Resources>
    <ResourceDictionary Source="pack://application:,,,/Smack.Core.Presentation.Wpf;component/Themes/generic.xaml" />
</UserControl.Resources>

<Button x:Name="_button" Style="{StaticResource blueButtonStyle}" Command="{Binding AddNewItemCommand}"  >
    <StackPanel Orientation="Horizontal" >
        <Image Source="{resx:Resx ResxName=Smack.Core.Presentation.Resources.MasterDetail, Key=bullet_add}" Stretch="Uniform" VerticalAlignment="Center" />
        <AccessText x:Name="_accesText" VerticalAlignment="Center">_Add New Subject</AccessText>
        <ContentPresenter/>
    </StackPanel>
</Button>

UserControl代码后台:

public partial class AddNewItemButton : UserControl
{
    public AddNewItemButton() { InitializeComponent(); }

    public static readonly DependencyProperty SubjectProperty = DependencyProperty.Register(
        "Subject", typeof (string), typeof (AddNewItemButton),
        new FrameworkPropertyMetadata(OnSubjectChanged));

    public string Subject { get { return (string) GetValue(SubjectProperty); } set { SetValue(SubjectProperty, value); } }

    private static void OnSubjectChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) {
        var control = obj as AddNewItemButton;
        if (control == null) return;

        control._accesText.Text = "_" + string.Format(MasterDetail.Subject_AddNew_Label, control.Subject.Capitalize());

        control._button.ToolTip = string.Format(MasterDetail.Subject_AddNew_ToolTip, control.Subject.ToLower());
    }

}

创建自定义控件失败:

public class MyButton : Button
{
    public static readonly DependencyProperty SubjectProperty = DependencyProperty.Register(
        "ItemName", typeof(string), typeof(MyButton),
        new FrameworkPropertyMetadata(OnSubjectChanged));

    public string Subject
    {
        get { return (string)GetValue(SubjectProperty); }
        set { SetValue(SubjectProperty, value); }
    }

    private static void OnSubjectChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        var control = obj as MyButton;
        if (control == null) return;

        ToolTip = ??;
    }
}

更新

根据Phil的回答,控件(底部的那个)比我想象中更加“无样式”:--)

结果

代码

 public class AddNewItemButton : Button
{
    static AddNewItemButton() {
        var type = typeof (AddNewItemButton);
        DefaultStyleKeyProperty.OverrideMetadata(type, new FrameworkPropertyMetadata(type));
    }

    #region Subject

    public static readonly DependencyProperty SubjectProperty = DependencyProperty.Register(
        "Subject", typeof(string), typeof(AddNewItemButton),
        new PropertyMetadata(default(string)));

    public string Subject
    {
        get { return (string)GetValue(SubjectProperty); }
        set { SetValue(SubjectProperty, value); }
    }

    #endregion

}

Generic.xaml

<Style TargetType="{x:Type local:AddNewItemButton}">

    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=Subject, Converter={StaticResource AddNewItemForToolTip}}"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:AddNewItemButton}">
                <Border Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>

                        <Image Stretch="Uniform" VerticalAlignment="Center"
                            Source="{resx:Resx ResxName=Smack.Core.Presentation.Resources.MasterDetail, Key=bullet_add}" />

                        <AccessText 
                            Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Subject, Converter={StaticResource AddNewItemForLabel}}" />

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

enter image description here

1个回答

3
这是一个自定义按钮和工具提示的示例(基于您最近提出的问题):
这是代码。
public class CustomButton : Button
{
    static CustomButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomButton), 
           new FrameworkPropertyMetadata(typeof(CustomButton)));
    }

    public static readonly DependencyProperty SubjectProperty =
        DependencyProperty.Register("Subject", typeof (string),
        typeof (CustomButton), new PropertyMetadata(default(string)));

    public string Subject
    {
        get { return (string) GetValue(SubjectProperty); }
        set { SetValue(SubjectProperty, value); }
    }
}

这个内容放在Themes/generic.xaml文件中。

<System:String x:Key="Test">Add new: </System:String>

<Style TargetType="{x:Type local:CustomButton}">
    <Setter Property="ToolTip" 
            Value="{Binding RelativeSource={RelativeSource Self}, Path=Subject}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomButton}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>

                        <Label Grid.Column="0" Content="Image here" 
                               VerticalAlignment="Center" Padding="0,0,5,0"/>

                        <AccessText Grid.Column="1" VerticalAlignment="Center">
                            <AccessText.Text>
                                <MultiBinding StringFormat="{}_{0} {1}">
                                    <Binding Source="{StaticResource Test}"/>
                                    <Binding RelativeSource=
                                        "{RelativeSource TemplatedParent}" 
                                        Path="Subject"/>
                                </MultiBinding>
                            </AccessText.Text>
                        </AccessText>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

感谢您在使用不同技术方面的帮助。我无法让自定义控件做太多事情,但是我发布了我的代码(请参见更新的帖子),希望您能发现明显的问题。谢谢。 - Berryl
虽然用于其他目的,但是 Binding {RelativeSource TemplatedParent} 对我来说非常有用。谢谢。 - DRapp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接