我有一个从Tableau
派生的类Windows.Controls.Control
,其模板包含一个Canvas
:
<Style TargetType="{x:Type local:Tableau}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Tableau}">
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ScrollViewer x:Name="ScrollViewer"
HorizontalScrollBarVisibility="{Binding RelativeSource={RelativeSource TemplatedParent},Path=HorizontalScrollBarVisibility}"
VerticalScrollBarVisibility="{Binding RelativeSource={RelativeSource TemplatedParent},Path=VerticalScrollBarVisibility}"
>
<Canvas x:Name="Diagram"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Background}"
>
<Canvas.RenderTransform>
<ScaleTransform CenterX="0"
CenterY="0"
ScaleX="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Scale}"
ScaleY="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Scale}"
/>
</Canvas.RenderTransform>
</Canvas>
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
并且Tableau
类为:
public class Tableau:Control
{
private Canvas _canvas;
public Canvas Canvas
{
get { return _canvas; }
}
static Tableau()
{
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(
typeof(Tableau), new FrameworkPropertyMetadata(typeof(Tableau)));
}
public Tableau()
: base()
{
this.Loaded += Tableau_Loaded;
}
private void Tableau_Loaded(object sender, RoutedEventArgs e)
{
_canvas = (Canvas)this.Template.FindName("Diagram", this);
}
}
我想将其用作画布,如下所示:
<local:Tableau>
<Rectangle Fill="AliceBlue" Stroke="Black" Width="100" Height="100" Canvas.Top="10"/>
<Rectangle Fill="AliceBlue" Stroke="Black" Width="100" Height="100" Canvas.Left="130" Canvas.Top="50"/>
</local:Tableau>
是否可以,如果可以,怎么办?
您可以定义属性Children
,让它从内部Children
返回Canvas
集合,并应用ContentProperty
属性。这是我测试的类的修改版本:
ContentProperty
请注意,我使用[ContentProperty(nameof(Children))]
public class Tableau : Control
{
static Tableau()
{
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(
typeof(Tableau), new FrameworkPropertyMetadata(typeof(Tableau)));
}
private Canvas canvas;
public Canvas Canvas
{
get
{
if (canvas == null) { ApplyTemplate(); }
return canvas;
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
canvas = (Canvas)GetTemplateChild("Diagram");
}
public UIElementCollection Children { get { return Canvas.Children; }
}
}
而不是OnApplyTemplate
,因此即使在Loaded
加载之前,我也可以获得内部Canvas
(因此也可以获取Children
集合)。
由于某种原因,有时会抛出Tableau
,但仅在设计视图中。运行它时效果很好。