私はカスタムWPFコントロールで作業しています。このコントロールの主な目的は、スクロール可能領域に数千のグラフィカルプリミティブを視覚化することです。コントロールのテンプレートの中核部分は次のようになります。カスタムWPFコントロールのカスタム描画UIElementの再描画を強制します
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ItemVisualizer}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<local:ItemAreaElement Grid.Row="0" Grid.Column="0" x:Name="PART_ItemArea" />
<ScrollBar Grid.Row="0" Grid.Column="1" x:Name="PART_ScrollBarVert" Orientation="Vertical" Maximum="100" />
<ScrollBar Grid.Row="1" Grid.Column="0" x:Name="PART_ScrollBarHorz" Orientation="Horizontal" Maximum="100" />
<Rectangle Grid.Row="1" Grid.Column="1" x:Name="PART_SizeGrip" Focusable="False" Fill="#F0F0F0" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
ItemAreaElementはアイテムを描画します。
class ItemAreaElement : FrameworkElement
{
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
for (int i = 0; i < _data.ItemCount; i++)
{
drawingContext.DrawLine(_penLine, new Point(0, i * 10), new Point(100, i * 10));
}
}
}
私はItemAreaElementに全体ItemVisualizer制御変化の関連プロパティたびに再描画する必要があります。簡単にするために、我々はそのコア部分はこのようになっていることを考えることができますしかし、私はWPFでそれを行う方法を見つけませんでした。ディスパッチャオブジェクトとよく知っているトリックは、私の場合には動作しません:_itemAreaがItemAreaElementへのローカル参照です
private static void OnItemCountPropertyChanged(DependencyObject source,
DependencyPropertyChangedEventArgs e)
{
ItemVisualizer vis = (ItemVisualizer)source;
vis._itemArea.Dispatcher.Invoke(delegate { }, DispatcherPriority.Render);
}
は、OnApplyTemplate()で得た:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (this.Template != null)
{
_itemArea = this.Template.FindName("PART_ItemArea", this) as ItemAreaElement;
_itemArea.Grid = this;
}
}
がする他の方法があります私の工事でUIElementの更新を強制しますか?それとも可能にするためにコントロール全体を再設計する必要がありますか?
「vis._itemArea.InvalidateArrange()」または「vis._itemArea.InvalidateVisual()」を呼び出すことはできません。 – Clemens
おそらく、ItemVisualizerプロパティの登録時に 'FrameworkPropertyMetadataOptions.AffectsRender'を設定するだけですか? – Clemens
@Clemens、ItemVisualizerはオブジェクトであり、プロパティではありません。しかし、 'UIElement.InvalidateVisual()'は助けます、なぜ私はそれを見落としたのか分かりません。あなたは答えではなく、コメントとして投稿することができます。 – TecMan