スクロール可能な領域に何千ものグラフィック プリミティブを視覚化するカスタム WPF コントロールに取り組んでいます。コントロールのテンプレートのコア部分は次のとおりです。
<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 の OnRender メソッドで実行されます。鮮明な描画を行うために、初期化コードで次の設定も使用します。
this.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);
しかし、私の絵にはいくつかの奇妙な問題があります。それらを示すために、ItemAreaElement の定義を次のように単純化しました。
class ItemAreaElement : FrameworkElement
{
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
const int ITEM_WIDTH = 60;
const int ITEM_HEIGHT = 20;
Pen penRed = new Pen(Brushes.Red, 1);
Pen penGreen = new Pen(Brushes.Green, 1);
int y = 0;
for (int iRow = 0; iRow < 3; iRow++)
{
int x = 0;
for (int iCol = 0; iCol < 2; iCol++)
{
Point cornerTopLeft = new Point(x, y);
dc.DrawLine(penRed, cornerTopLeft, new Point(x + ITEM_WIDTH - 1, y));
dc.DrawLine(penRed, cornerTopLeft, new Point(x, y + ITEM_HEIGHT - 1));
Point cornerBottomRight = new Point(x + ITEM_WIDTH - 1, y + ITEM_HEIGHT - 1);
dc.DrawLine(penGreen, new Point(x + ITEM_WIDTH - 1, y), cornerBottomRight);
dc.DrawLine(penGreen, new Point(x, y + ITEM_HEIGHT - 1), cornerBottomRight);
x += ITEM_WIDTH;
}
y += ITEM_HEIGHT;
}
}
}
このコードを 282ppi の Ultra-HD 画面 (システム スケール ファクターは 300%) を備えたメインの開発用ラップトップで起動すると、次の画像が表示されます。
または、グリッド線で paint.net を拡大した後:
ご覧のとおり、ItemAreaElement の左端と上端は、コントロールの境界線で部分的に覆われています。そうでなければなりませんか?これを回避するために使用できる設定はありますか?
2 番目の問題は、開始点を含まない行です (「セル」の左上隅を参照してください)。これは予想される動作ですか?もしそうなら、WPFに強制的に開始ピクセルを描画させる方法は?
3 つ目の問題は、緑色の線が交わる場所またはデバイスに依存しないポイント (セルの右下隅) です。ご覧のとおり、この点はギザギザです。その場所には緑色の四角が見えるだけだと思っていました。DrawingContext.DrawLine メソッドを使用してこれを実装できますか? または、マルチポイント ラインなどに特別な設定を加えた、より複雑なジオメトリを使用する必要がありますか?
ところで、このコードを「クラシック」96 ppi モニターと 100% に設定された OS のスケール ファクターを備えたテスト PC で起動すると、状況は右下隅で少し良くなります。
しかし、一番上の行の赤い横線や最初の列の赤い縦線さえ見えません。そこにそれらが表示されることを期待していましたが、コントロールの境界線で覆われていないことを期待していました. これらの問題をすべて解決する方法を知っている場合は、教えてください。