Wpf 如何在资源字典中放置依赖项属性以实现重用?

Wpf 如何在资源字典中放置依赖项属性以实现重用?,wpf,xaml,resourcedictionary,Wpf,Xaml,Resourcedictionary,我有以下课程 public class ChartBase:FrameworkElement, INotifyPropertyChanged { public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(nameof(Header), typeof(object),typeof(ChartBase)); public object Header {

我有以下课程

public class ChartBase:FrameworkElement, INotifyPropertyChanged
{ 
    public static readonly DependencyProperty HeaderProperty = 
    DependencyProperty.Register(nameof(Header), typeof(object),typeof(ChartBase));

   public object Header
   {
    get { return (bool)GetValue(IsSpinningProperty); }
    set { SetValue(IsSpinningProperty, value); }
  }

}
通常这是我在XAML中使用它的方式:

    <ChartBase.Header>
        <TextBlock Foreground="Black" 
                   FontFamily="Segoe UI" 
                   Margin="0,0,0,20" 
                   Text="{Binding Header}"
                   HorizontalAlignment="Center" 
                   VerticalAlignment="Center" />
    </ChartBase.Header>

如何做到这一点(同时
DataContext.Header
)仍然正确绑定?如果这是不可能的,那么编写代码的下一个最佳方法是什么,以便这些头信息可以轻松重用?

首先,FrameworkElement无法模板化,因此我建议降低一级(更高?),改用Control:

然后在你的ChartBase HeaderProperty中,你得到并设置了其他东西

我允许自己这样修改它:

public class ChartBase : Control, INotifyPropertyChanged
{
    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.Register(nameof(Header), typeof(object), typeof(ChartBase));

    public object Header
    {
        get => (bool)GetValue(HeaderProperty);
        set => SetValue(HeaderProperty, value);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
 <Window.Resources>
    <Style TargetType="{x:Type myProject:ChartBase}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type myProject:ChartBase}">
                    <TextBlock Foreground="Red" 
                           FontFamily="Segoe UI" 
                           Margin="0,0,0,20" 
                           Text="{TemplateBinding Header}"
                           HorizontalAlignment="Center" 
                           VerticalAlignment="Center" />
                </ControlTemplate>

            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
然后你可以这样设计它:

public class ChartBase : Control, INotifyPropertyChanged
{
    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.Register(nameof(Header), typeof(object), typeof(ChartBase));

    public object Header
    {
        get => (bool)GetValue(HeaderProperty);
        set => SetValue(HeaderProperty, value);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
 <Window.Resources>
    <Style TargetType="{x:Type myProject:ChartBase}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type myProject:ChartBase}">
                    <TextBlock Foreground="Red" 
                           FontFamily="Segoe UI" 
                           Margin="0,0,0,20" 
                           Text="{TemplateBinding Header}"
                           HorizontalAlignment="Center" 
                           VerticalAlignment="Center" />
                </ControlTemplate>

            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

最后,用法如下:

<myProject:ChartBase Header="My Header" /> 
<!--Header can be bound to any property you want-->

可以在样式中声明头属性的setter:

<TextBlock x:Key="hdr" x:Shared="False"
           Foreground="Black" 
           FontFamily="Segoe UI" 
           Margin="0,0,0,20" 
           Text="{Binding Header}"
           HorizontalAlignment="Center" 
           VerticalAlignment="Center" />

<Style TargetType="ChartBase" x:Key="SecondGB">
    <Setter Property="Header" Value="{StaticResource hdr}"/>
</Style>

但是它只创建一个TextBlock实例,它只能在一个地方显示

我想你是说ChartBase的样式,其中标题是TextBlock?您不能将属性本身放在资源字典中。@NawedNabiZada,是的,我想要一个ChartBase的样式
GroupBox
与您将
标题
属性设置为的
TextBlock
有什么关系?您确定这是正确的吗?似乎
标题设置为
System.Windows.Style
类型,而不是
TextBlock
@Graviton,我没有ChartBase,但它适用于Button.content似乎
Setter Property=“Template”
替换了
myProject:ChartBase
中的内容,而不是
myProject:ChartBase.Header中的内容,这是正确的。不能为属性设置模板。如果您真的只想设置标题的样式/模板,则将其从类型对象更改为其他类型(例如控件),并将样式/模板基于该类型。如果标题的类型为
对象,而我无法更改它(因为控件来自我无权访问的第三方),该怎么办?您想如何将对象绑定到TextBlock的文本属性?我想我不太理解您对这个图表库的用法。依赖项属性意味着要绑定。如果您已经有了一个Header属性,并且希望将其绑定到一个TextBlock,那么请使用提供的答案。但是,如果控件中没有标头属性,并且希望添加一个,那么必须创建已创建的依赖项属性。