WPF 控件模板:为什么在显而易见的地方需要 TargetType?
WPF control template : why TargetType is required where its obvious?
我对wpf中xaml的过度冗长感到有点困惑。例如在定义控件模板时,您仍然必须将目标类型指定为控件本身。是否需要指定 TargetType?因为我正在定义 TargetControl 的模板元素,所以在未指定时它不会默认为 TargetControl 吗?
<local:TargetControl Width="100" Height="100">
<local:TargetControl.Template>
<ControlTemplate TargetType="local:TargetControl">
<Grid>
<Ellipse x:Name="PART_Target" Fill="Blue" />
<Grid>
</ControlTemplate>
</local:TargetControl.Template>
</local:TargetControl>
标记 <ControlTemplate> </ControlTemplate>
表示使用默认构造函数 (new ControlTemplate()
) 创建新的 ControlTemplate 实例。构造函数不知道哪个元素将使用模板。
在这个例子中
<ControlTemplate TargetType="local:TargetControl">
<Grid>
<Ellipse x:Name="PART_Target" Fill="Blue" />
<Grid>
</ControlTemplate>
模板可以在没有 TargetType 的情况下使用,因为它不使用 TemplateBinding
的任何 TargetControl
特定属性。如果需要 TemplateBindings,还必须设置 TargetType。
在大多数情况下,元素模板具有与元素类型相同的 TargetType。
但也可能存在特殊情况,例如:我希望我的 RadioButtons 和 CheckBoxes 看起来像彩色圆圈 - 选中时为绿色,未选中时为灰色。
RadioButton 和 CheckBox 派生自 ToggleButton,因此我为 ToggleButton 创建模板并应用于我的 RadioButton 和 CheckBox:
<StackPanel>
<StackPanel.Resources>
<ControlTemplate TargetType="{x:Type ToggleButton}" x:Key="Toggle">
<Border Name="btn" BorderBrush="Black" Background="Gainsboro"
Width="28" Height="28" CornerRadius="14" />
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" TargetName="btn" Value="Lime" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</StackPanel.Resources>
<CheckBox Template="{StaticResource Toggle}" />
<RadioButton Template="{StaticResource Toggle}" />
<RadioButton Template="{StaticResource Toggle}" />
</StackPanel>
这个例子还演示了当ControlTemplate在资源字典中定义时没有连接到特定元素的情况,因此无法推断出TargetType。
所以至少有 3 种情况下 TargetType 不确定或不需要。所以留给开发人员始终提供具体类型
我对wpf中xaml的过度冗长感到有点困惑。例如在定义控件模板时,您仍然必须将目标类型指定为控件本身。是否需要指定 TargetType?因为我正在定义 TargetControl 的模板元素,所以在未指定时它不会默认为 TargetControl 吗?
<local:TargetControl Width="100" Height="100">
<local:TargetControl.Template>
<ControlTemplate TargetType="local:TargetControl">
<Grid>
<Ellipse x:Name="PART_Target" Fill="Blue" />
<Grid>
</ControlTemplate>
</local:TargetControl.Template>
</local:TargetControl>
标记 <ControlTemplate> </ControlTemplate>
表示使用默认构造函数 (new ControlTemplate()
) 创建新的 ControlTemplate 实例。构造函数不知道哪个元素将使用模板。
在这个例子中
<ControlTemplate TargetType="local:TargetControl">
<Grid>
<Ellipse x:Name="PART_Target" Fill="Blue" />
<Grid>
</ControlTemplate>
模板可以在没有 TargetType 的情况下使用,因为它不使用 TemplateBinding
的任何 TargetControl
特定属性。如果需要 TemplateBindings,还必须设置 TargetType。
在大多数情况下,元素模板具有与元素类型相同的 TargetType。
但也可能存在特殊情况,例如:我希望我的 RadioButtons 和 CheckBoxes 看起来像彩色圆圈 - 选中时为绿色,未选中时为灰色。
RadioButton 和 CheckBox 派生自 ToggleButton,因此我为 ToggleButton 创建模板并应用于我的 RadioButton 和 CheckBox:
<StackPanel>
<StackPanel.Resources>
<ControlTemplate TargetType="{x:Type ToggleButton}" x:Key="Toggle">
<Border Name="btn" BorderBrush="Black" Background="Gainsboro"
Width="28" Height="28" CornerRadius="14" />
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" TargetName="btn" Value="Lime" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</StackPanel.Resources>
<CheckBox Template="{StaticResource Toggle}" />
<RadioButton Template="{StaticResource Toggle}" />
<RadioButton Template="{StaticResource Toggle}" />
</StackPanel>
这个例子还演示了当ControlTemplate在资源字典中定义时没有连接到特定元素的情况,因此无法推断出TargetType。
所以至少有 3 种情况下 TargetType 不确定或不需要。所以留给开发人员始终提供具体类型