简体   繁体   中英

Binding Canvas Background in Generic.xaml for custom control

In WPF, I have a Canvas to which I am drawing horizontal lines across the background, something like a notepad with ruled lines. The spacing of these lines is bound to the viewmodel. The below code works well.

I now would like to convert the canvas, its background, and the applied behavior into a single customcontrol. The basic problem, ofcourse, is that a Canvas does not have a Template property, so TemplateBinding from Generic.XAML is out.

How can this be done? Any help or suggestions is most appreciated.

TIA

XAML

<!--This style used to draw background lines on the notepad canvas.-->
 <Style x:Key="notepadLines" TargetType="{x:Type Canvas}">
            <Setter Property="Background">
                <Setter.Value>
                    <DrawingBrush Stretch="None" TileMode="Tile"  ViewportUnits="Absolute">
                        <DrawingBrush.Viewport>
                            <MultiBinding>
                                <MultiBinding.Converter>
                                    <conv:RectConverter/>
                                </MultiBinding.Converter>
                                <Binding Path="WritingLayer.MainCanvas.ViewPortWidth"/>
                                <Binding Path="WritingLayer.MainCanvas.ViewPortHeight"/>
                            </MultiBinding>
                        </DrawingBrush.Viewport>
                        <DrawingBrush.Drawing>
                            <DrawingGroup>
                                <DrawingGroup.Children>
                                    <GeometryDrawing>
                                        <GeometryDrawing.Brush>
                                            <SolidColorBrush Color="Purple" Opacity="0.2" />
                                        </GeometryDrawing.Brush>
                                        <GeometryDrawing.Pen>
                                            <Pen Thickness="1" Brush="LightGreen"/>
                                        </GeometryDrawing.Pen>
                                        <GeometryDrawing.Geometry>
                                            <RectangleGeometry>
                                                <RectangleGeometry.Rect>
                                                    <MultiBinding>
                                                        <MultiBinding.Converter>
                                                            <conv:DrawingBoxConverter/>
                                                        </MultiBinding.Converter>
                                                        <Binding Path="WritingLayer.MainCanvas.DrawingBoxTop"/>
                                                        <Binding Path="WritingLayer.MainCanvas.ViewPortWidth"/>
                                                        <Binding Path="WritingLayer.MainCanvas.DrawingBoxHeight"/>
                                                    </MultiBinding>
                                                </RectangleGeometry.Rect>
                                            </RectangleGeometry>
                                        </GeometryDrawing.Geometry>
                                    </GeometryDrawing>
                                    <GeometryDrawing>
                                        <GeometryDrawing.Geometry>
                                            <GeometryGroup>
                                                <LineGeometry StartPoint="0,0" EndPoint="{Binding WritingLayer.MainCanvas.EndPointHeight}"/>
                                                <LineGeometry StartPoint="0,0" EndPoint="{Binding WritingLayer.MainCanvas.EndPointWidth}"/>
                                            </GeometryGroup>
                                        </GeometryDrawing.Geometry>
                                        <GeometryDrawing.Pen>
                                            <Pen Thickness="1" Brush="Green"/>
                                        </GeometryDrawing.Pen>
                                    </GeometryDrawing>
                                    <GeometryDrawing>
                                        <GeometryDrawing.Geometry>
                                            <GeometryGroup>
                                                <LineGeometry StartPoint="{Binding WritingLayer.MainCanvas.StartPointMidline}" 
                                                              EndPoint="{Binding WritingLayer.MainCanvas.EndPointMidline}"/>
                                            </GeometryGroup>
                                        </GeometryDrawing.Geometry>
                                        <GeometryDrawing.Pen>
                                            <Pen Thickness="1" Brush="Red">
                                                <Pen.DashStyle>
                                                    <DashStyle Dashes="4,12"/>
                                                </Pen.DashStyle>
                                            </Pen>
                                        </GeometryDrawing.Pen>
                                    </GeometryDrawing>
                                </DrawingGroup.Children>
                            </DrawingGroup>
                        </DrawingBrush.Drawing>
                    </DrawingBrush>
                </Setter.Value>
            </Setter>
        </Style>



 <Canvas x:Name="NotePad" Grid.Column="1"  Grid.Row="1" 
                    Visibility="{Binding WritingLayer.IsWriting, Converter={StaticResource BoolToVisibilityConverter}}"
                    Style="{StaticResource notepadLines}" 
                    >
                <i:Interaction.Behaviors>
                    <b:NotePadBackgroundBehavior/>
                </i:Interaction.Behaviors>
 </Canvas>

Create a custom control that has a Canvas in its ControlTemplate .

Generic.xaml:

    <Style TargetType="local:CustomControl">
        <Setter Property="Template">
            <Setter.Value>
                <Canvas>
                    <Canvas.Background>
                        <DrawingBrush Stretch="None" TileMode="Tile"  ViewportUnits="Absolute">
                            ...
                        </DrawingBrush>
                    </Canvas.Background>
                </Canvas>
            </Setter.Value>
        </Setter>
    </Style>

Control:

public class CustomControl : Control
{
    static CustomControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl),
            new FrameworkPropertyMetadata(typeof(CustomControl)));
    }

    //... + any properties...

}

Usage:

<local:CustomControl />

OK, made a few changes. The below does compile correctly:

<Style TargetType="{x:Type local:NotePad}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate  TargetType="local:NotePad">
                    <Canvas>
                        <Canvas.Background>
                            <DrawingBrush Stretch="None" TileMode="Tile"  ViewportUnits="Absolute">
                                <DrawingBrush.Viewport>
                                    <MultiBinding>
                                        <MultiBinding.Converter>
                                            <conv:RectConverter/>
                                        </MultiBinding.Converter>
                                        <Binding Path="{TemplateBinding ViewPortWidth}"/>
                                        <Binding Path="{TemplateBinding ViewPortHeight}"/>

                                    </MultiBinding>
                                </DrawingBrush.Viewport>

........................................................

 public class NotePad : Control
    {
        static NotePad()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(NotePad), new FrameworkPropertyMetadata(typeof(NotePad)));
        }

        #region [ViewPortWidth]
        public double ViewPortWidth
        {
            get { return (double)GetValue(ViewPortWidthProperty); }
            set { SetValue(ViewPortWidthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ViewPortWidth.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ViewPortWidthProperty =
            DependencyProperty.Register("ViewPortWidth", typeof(double), typeof(NotePad), new PropertyMetadata(0.0));

        #endregion

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM