我创建了一个包含两个TemplateParts的CustomControl。
using System;
using System.Windows;
using System.Windows.Controls;
namespace WpfCustomControlLibrary1
{
[TemplatePart(Name = "PART_ControlsLayer", Type = typeof (ContentPresenter))]
[TemplatePart(Name = "PART_DisplayLayer", Type = typeof (ContentPresenter))]
public class CustomControl1 : Control
{
public static readonly DependencyProperty ControlsLayerProperty =
DependencyProperty.Register("ControlsLayer", typeof (object), typeof (CustomControl1),
new UIPropertyMetadata(null));
public static readonly DependencyProperty DisplayLayerProperty =
DependencyProperty.Register("DisplayLayer", typeof (object), typeof (CustomControl1),
new UIPropertyMetadata(null));
private ContentPresenter partControlsLayer;
private ContentPresenter partDisplayLayer;
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof (CustomControl1),
new FrameworkPropertyMetadata(typeof (CustomControl1)));
}
public object ControlsLayer
{
get { return GetValue(ControlsLayerProperty); }
set { SetValue(ControlsLayerProperty, value); }
}
public object DisplayLayer
{
get { return GetValue(DisplayLayerProperty); }
set { SetValue(DisplayLayerProperty, value); }
}
public override void OnApplyTemplate()
{
ApplyTemplate();
partControlsLayer = GetTemplateChild("PART_ControlsLayer") as ContentPresenter;
partDisplayLayer = GetTemplateChild("PART_DisplayLayer") as ContentPresenter;
if (partControlsLayer == null || partDisplayLayer == null)
{
throw new NullReferenceException("Template parts not available");
}
}
}
}
在Generic.xaml中,我为DisplayLayer(其中一个TemplateParts)定义了ControlTemplate和Default-Setter。最后我将其设置为CustomControl1的模板。
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCustomControlLibrary1">
<Style TargetType="{x:Type local:CustomControl1}">
<Style.Resources>
<ControlTemplate x:Key="DefaulTemplate" TargetType="{x:Type local:CustomControl1}">
<Grid>
<ContentPresenter x:Name="PART_ControlsLayer"
Content="{TemplateBinding ControlsLayer}" />
<ContentPresenter x:Name="PART_DisplayLayer"
Content="{TemplateBinding DisplayLayer}" />
</Grid>
</ControlTemplate>
</Style.Resources>
<Setter Property="DisplayLayer">
<Setter.Value>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="{Binding FunctionName, FallbackValue=Functionname}" />
<TextBlock Grid.Row="1" Text="{Binding DisplayValue, FallbackValue=0.0dB}" Foreground="Lime"
Background="Black" />
</Grid>
</Setter.Value>
</Setter>
<Setter Property="Template" Value="{StaticResource DefaulTemplate}"/>
</Style>
<Style TargetType="{x:Type local:CustomControl2}" BasedOn="{StaticResource {x:Type local:CustomControl1}}" />
</ResourceDictionary>
现在我创建一个CustomControl2 BasedOn CustomControl1。
using System.Windows;
namespace WpfCustomControlLibrary1
{
public class CustomControl2 : CustomControl1
{
static CustomControl2()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl2), new FrameworkPropertyMetadata(typeof(CustomControl2)));
}
}
}
然后我将两个控件放在WpfWindow上。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfCustomControlLibrary1="clr-namespace:WpfCustomControlLibrary1;assembly=WpfCustomControlLibrary1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<wpfCustomControlLibrary1:CustomControl1 Grid.Row="0"/>
<wpfCustomControlLibrary1:CustomControl2 Grid.Row="1"/>
</Grid>
</Window>
问题是我只在第二个控件上看到Defaulttemplate。我无法找到解决方案,请帮助。
@ gomi42 - 如果我将Generic.xaml更改为:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCustomControlLibrary1">
<Style x:Key="BaseStyle" TargetType="{x:Type local:CustomControl1}">
<Style.Resources>
<ControlTemplate x:Key="DefaulTemplate" TargetType="{x:Type local:CustomControl1}">
<Grid>
<ContentPresenter x:Name="PART_ControlsLayer"
Content="{TemplateBinding ControlsLayer}" />
<ContentPresenter x:Name="PART_DisplayLayer"
Content="{TemplateBinding DisplayLayer}" />
</Grid>
</ControlTemplate>
</Style.Resources>
<Setter Property="Template" Value="{StaticResource DefaulTemplate}"/>
<Setter Property="DisplayLayer">
<Setter.Value>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="{Binding FunctionName, FallbackValue=Functionname}" />
<TextBlock Grid.Row="1" Text="{Binding DisplayValue, FallbackValue=0.0dB}" Foreground="Lime"
Background="Black" />
</Grid>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:CustomControl1}" BasedOn="{StaticResource BaseStyle}" />
<Style TargetType="{x:Type local:CustomControl2}" BasedOn="{StaticResource BaseStyle}" />
</ResourceDictionary>
没有什么变化!它仅在第二个控件中可见。
答案 0 :(得分:0)
您创建的样式仅适用于CustomControl1:
<Style TargetType="{x:Type local:CustomControl1}">
...
您需要为CustomControl2创建一个新样式,例如通过继承:
<Style x:Key="MyBase" TargetType="{x:Type local:CustomControl1}">
...
</Style>
<Style TargetType="{x:Type local:CustomControl1}" BasedOn={StaticResource MyBase} />
<Style TargetType="{x:Type local:CustomControl2}" BasedOn={StaticResource MyBase} />
答案 1 :(得分:0)
我找到了它!
导致问题的是DependencyProperty。我像本网站上的示例一样实现了CustomControl: http://www.kunal-chowdhury.com/2011/04/how-to-implement-template-binding-in.html
我该怎么说这个例子是错的!
以下是它的工作原理。
第一个CustomControl.cs
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using WpfCustomControlLibrary1.Annotations;
namespace WpfCustomControlLibrary1
{
[TemplatePart(Name = "PART_ControlsLayer", Type = typeof (Grid))]
[TemplatePart(Name = "PART_DisplayLayer", Type = typeof(ContentControl))]
public class CustomControl1 : Control
{
private Grid partControlsLayer;
private ContentControl partDisplayLayer;
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof (CustomControl1),
new FrameworkPropertyMetadata(typeof (CustomControl1)));
}
public CustomControl1()
{
DataContext = this;
}
public override void OnApplyTemplate()
{
ApplyTemplate();
partControlsLayer = GetTemplateChild("PART_ControlsLayer") as Grid;
partDisplayLayer = GetTemplateChild("PART_DisplayLayer") as ContentControl;
if (partControlsLayer == null || partDisplayLayer == null)
{
//throw new NullReferenceException("Template parts not available");
}
}
}
}
然后是Generic.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCustomControlLibrary1">
<Style x:Key="DefaultTemplate" TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="{Binding FunctionName, FallbackValue=Functionname}" />
<TextBlock Grid.Row="1" Text="{Binding DisplayValue, FallbackValue=0.0dB}" Foreground="Lime"
Background="Black" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ContentControl x:Name="PART_DisplayLayer" Style="{StaticResource DefaultTemplate}" />
<Grid x:Name="PART_ControlsLayer" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="{Binding FunctionName, FallbackValue=Functionname}" />
<Button Grid.Row="1" Content="{Binding DisplayValue, FallbackValue=0.5dB}" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:CustomControl2}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ContentControl x:Name="PART_DisplayLayer" Style="{StaticResource DefaultTemplate}" />
<Grid x:Name="PART_ControlsLayer" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="Depp" />
<Button Grid.Row="1" Content="{Binding DisplayValue, FallbackValue=1.0dB}" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
CustomControl2.cs作为Derived-Class
using System.Windows;
namespace WpfCustomControlLibrary1
{
public class CustomControl2 : CustomControl1
{
static CustomControl2()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl2), new FrameworkPropertyMetadata(typeof(CustomControl2)));
}
public CustomControl2()
{
DataContext = this;
}
}
}
MainWindow仍然是一样的。
这是有效的,因为没有任何内容是静态的。