[英]WPF Encapsulate rectangle with StaticResource as fill to a CustomControl in WPF
I am using ModernUIIcons that come with MahApps.Metro in a Xaml file as StaticResources. 我在Xaml文件中使用MahApps.Metro随附的ModernUIIcons作为StaticResources。 To put one in my UI is very easy, like this:
在我的用户界面中放置一个非常简单,如下所示:
<Rectangle Width="19"
Height="19">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource appbar_database}" />
</Rectangle.Fill>
</Rectangle>
I want to encapsulate all the logic of the rectangle in a CustomControl so I can do something like the following: 我想将矩形的所有逻辑封装在CustomControl中,以便可以执行以下操作:
<cc:MenuItemIcon Source="{StaticResource appbar_page}"/>
This is what I got so far: 这是我到目前为止所得到的:
In one project as library, Themes/Generic.xaml: 在一个作为库的项目中,Themes / 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:AMIGEDM.CustomControls.Menu">
<Style TargetType="{x:Type local:MenuItemIcon}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MenuItemIcon}">
<Rectangle Width="19"
Height="19">
<Rectangle.Fill>
<VisualBrush Visual="{TemplateBinding Source}" />
</Rectangle.Fill>
</Rectangle>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
And in the CS file 并在CS文件中
namespace AMIGEDM.CustomControls.Menu
{
public class MenuItemIcon : Control
{
static MenuItemIcon()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MenuItemIcon), new FrameworkPropertyMetadata(typeof(MenuItemIcon)));
}
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(Visual), typeof(MenuItemIcon));
public Visual Source
{
get { return (Visual)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
}
}
Everything compiles silky smooth, so I go to my TestDummy Project 一切都能如丝般顺滑地编译,所以我去了我的TestDummy项目
<Window x:Class="AMIGEDM.TestDummy.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:cc="clr-namespace:AMIGEDM.CustomControls.Menu;assembly=AMIGEDM.CustomControls">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/AMIGEDM.TestDummy;component/Resources/Icons.xaml"/>
<ResourceDictionary Source="pack://application:,,,/AMIGEDM.CustomControls;component/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Menu IsMainMenu="True" SnapsToDevicePixels="True">
<MenuItem Header="_Open">
<MenuItem Header="_File">
<MenuItem.Icon>
<cc:MenuItemIcon Source="{StaticResource appbar_page}"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="_File">
<MenuItem.Icon>
<Rectangle Width="19"
Height="19">
<Rectangle.Fill>
<VisualBrush Visual="{StaticResource appbar_database}" />
</Rectangle.Fill>
</Rectangle>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
</Grid>
The Library puts the Icon using the Rectangle, Rectangle Fill and VisualBrush, but when I try to use the CustomControl it shows nothing 库使用Rectangle,Rectangle Fill和VisualBrush放置Icon,但是当我尝试使用CustomControl时,它什么也没显示
All the code looks normal, except for the style of MenuItemIcon
. 除了
MenuItemIcon
的样式外,所有代码看起来都很正常。 Quote about TemplateBinding
from Adam Nathan book: 引用亚当·内森(Adam Nathan)的书中有关
TemplateBinding
内容:
TemplateBinding doesn't work outside a template or outside its VisualTree property, so you can't even use TemplateBinding inside a template's trigger.
TemplateBinding在模板外部或其VisualTree属性外部不起作用,因此您甚至不能在模板的触发器内使用TemplateBinding。 Furthermore, TemplateBinding doesn't work when applied to a Freezable (for mostly artificial reasons).
此外,将TemplateBinding应用于Freezable时不起作用(主要是出于人工原因)。
And quote from MSDN
about VisualBrush
: 并从
MSDN
引用有关VisualBrush
:
Freezable Features: Because it inherits from the Freezable class, the VisualBrush class provides several special features: VisualBrush objects can be declared as resources and shared among multiple objects.
Freezable功能:因为它继承自Freezable类,所以VisualBrush类提供了几个特殊功能:VisualBrush对象可以声明为资源并在多个对象之间共享。
Therefore instead of: 因此,代替:
<VisualBrush Visual="{TemplateBinding Source}" />
Use the construction {RelativeSource TemplatedParent}
and a Path
equal to the dependency property whose value you want to retrieve: 使用构造
{RelativeSource TemplatedParent}
和一个Path
等于要检索其值的依赖项属性:
<Style TargetType="{x:Type local:MenuItemIcon}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MenuItemIcon}">
<Rectangle Width="22" Height="22">
<Rectangle.Fill>
<VisualBrush Visual="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Source}" />
</Rectangle.Fill>
</Rectangle>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.