2017-08-10 67 views
0

在WPF中,我绘制了一个画布,我在背景中绘制水平线,就像记事本和划线一样。这些行的间距绑定到视图模型。以下代码运行良好。在Generic.xaml中为自定义控件绑定画布背景

我现在想将画布,背景和应用行为转换为一个自定义控件。当然,基本的问题是Canvas没有Template属性,所以Generic.XAML的TemplateBinding就没有了。

这怎么办?任何帮助或建议是非常感谢。

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> 
+0

只需创建自定义的'Control'并将其''Template'设置为具有所需样式的'Canvas'。然后,不要在任何地方使用“Canvas”,而是需要使用内衬表单,您将使用此自定义控件。 – Maxim

回答

1

创建在其ControlTemplate一个Canvas自定义控件。

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> 

控制:

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

    //... + any properties... 

} 

用法:

<local:CustomControl /> 
+0

nope ...无法使用TemplateBinding,并按照上面的方式导致“无法指定指定的值,以下是预期的类型:”ControlTemplate“。Setter.Value ...任何想法?谢谢。 –

+0

请参阅上文编辑,谢谢。 –

0

O.K,做了一些修改。以下编译正确:

<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