我正在尝试使用自己的绘图逻辑创建一个自定义控件(从Control派生)。该控件只是从控件的左上角到右下角绘制一条对角线。此逻辑基于控件的ActualWidth和ActualHeight,它们仅在呈现控件 (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 ) );
}
}