0

独自の描画ロジックを使用してカスタムコントロール( Controlから派生)を作成しようとしています。コントロールは、コントロールの左上隅から右下隅に対角線を引くだけです。このロジックは、コントロールのActualWidthActualHeightに基づいています。これらは、コントロールをレンダリングするときにのみ使用できます(AFAIK)。

私の質問は、カスタム描画を効率的に行うための適切な方法は何ですか?

これに関するドキュメントはあまりありません。OnPropertyChangedが起動されるたびに強制的に更新/再描画するなど、愚かなまたは不必要なことをしているのではないかと思います...

コントロールのテンプレートは次のとおりです。

<Style TargetType="{x:Type local:MyCustomControl}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type local:MyCustomControl}">
        <Border Background="{TemplateBinding Background}"
                BorderBrush="{TemplateBinding BorderBrush}"
                BorderThickness="{TemplateBinding BorderThickness}">
          <Canvas>
            <Line x:Name="PART_Diagonal"
                  Y1="{Binding Path=DiagonalTop}"
                  Y2="{Binding Path=DiagonalBottom}"
                  X1="{Binding Path=DiagonalLeft}"
                  X2="{Binding Path=DiagonalRight}"
                  Stroke="Red" />
          </Canvas>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

そして、ここにロジックがあります:

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

  public MyCustomControl()
  {
    DataContext = this;
  }

  protected override void OnRenderSizeChanged( SizeChangedInfo sizeInfo )
  {
    base.OnRenderSizeChanged( sizeInfo );

    var margin = 25d;

// These calculations are based on the control's current size.
    DiagonalTop = margin;
    DiagonalBottom = ActualHeight - margin;
    DiagonalLeft = margin;
    DiagonalRight = ActualWidth - margin;

// Is this forcing redraws (i.e. invalidating the layout)?
    OnPropertyChanged( "DiagonalTop" );
    OnPropertyChanged( "DiagonalBottom" );
    OnPropertyChanged( "DiagonalLeft" );
    OnPropertyChanged( "DiagonalRight" );
  }

  public double DiagonalTop { get; private set; }
  public double DiagonalBottom{ get; private set; }
  public double DiagonalLeft { get; private set; }
  public double DiagonalRight { get; private set; }

  public event PropertyChangedEventHandler PropertyChanged;
  protected void OnPropertyChanged(string propertyname)
  {
    if (PropertyChanged != null)
      PropertyChanged.Invoke( this, new PropertyChangedEventArgs( propertyname ) );
  }
}
4

1 に答える 1

3

追加のプロパティがなくても、はるかに簡単に実行できます。内側の間隔にPaddingプロパティを使用するだけです。

<ControlTemplate TargetType="{x:Type local:MyCustomControl}">
    <Border Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}" 
            BorderThickness="{TemplateBinding BorderThickness}"
            Padding="{TemplateBinding Padding}">
        <Canvas Name="DrawingCanvas">
            <Line X1="0" X2="{Binding ActualWidth, ElementName=DrawingCanvas}" 
                  Y1="0" Y2="{Binding ActualHeight, ElementName=DrawingCanvas}" 
                  Stroke="Red" />
        </Canvas>
    </Border>
</ControlTemplate>

パディングでコントロールを使用します。

<local:MyCustomControl Padding="25" ... />
于 2012-05-24T12:07:55.173 に答える