类派生的控件,在模板中具有Canvas,我想像画布一样工作

问题描述 投票:0回答:1

我有一个从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>

是否可以,如果可以,怎么办?

c# wpf templates canvas controls
1个回答
-1
投票

您可以定义属性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,但仅在设计视图中。运行它时效果很好。

© www.soinside.com 2019 - 2024. All rights reserved.