我正在尝试使用自己的绘图逻辑创建自定义控件(从 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 ) );
}
}
答案 0 :(得分: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" ... />