4

WPF の大きな問題の 1 つは、アンチ エイリアシングです。実際、WPF 4.0 でUseLayoutRendingが導入されたのはそのためです。ただし、次のサンプルでは機能しません。

<StackPanel UseLayoutRounding="True" TextOptions.TextFormattingMode="Display" >
    <Line X1="0" Y1="0" X2="200" Y2="0" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
    <Line X1="0" Y1="1.5" X2="200" Y2="1.5" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
    <Line X1="0" Y1="3.5" X2="200" Y2="3.5" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
    <Line X1="0" Y1="7" X2="200" Y2="7" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
    <Line X1="0" Y1="9" X2="200" Y2="9" StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True" UseLayoutRounding="True"></Line>
</StackPanel>

最後の 2 行はまだぼやけています。(私は Windows 7 を使用しています)

解決策はありますか?

それとも WPF 4.0 のベータ版のバグですか?

4

4 に答える 4

2

WPF で線をシャープに見せるのは非常に難しい場合があります。そして時々...黒魔術も少し必要なようです!

floele と Kimke の回答は正しい方向を向いていると思います。つまり、多くの場合、0.5 ピクセルの境界に単一のピクセル ラインを配置したい場合があります... ラインを描画する方法 (片側に半分、反対側に半分) を考えると。

ただし、それは必ずしもそれほど単純ではありません。たとえば、周囲の xaml にも依存します。たとえば、次のコードを試してサイズを変更します。

<Canvas HorizontalAlignment="Center" VerticalAlignment="Center">
    <Line X1="0" Y1="5" X2="200" Y2="5" StrokeThickness="1" Stroke="Black" UseLayoutRounding="True"/>
    <Line X1="0" Y1="15" X2="200" Y2="15" StrokeThickness="1" Stroke="Black" UseLayoutRounding="True"/>
</Canvas>

次に、このコードを試してください (再度、サイズを変更してください)。

<Canvas HorizontalAlignment="Center" VerticalAlignment="Center" UseLayoutRounding="True">
    <Line X1="0" Y1="5" X2="200" Y2="5" StrokeThickness="1" Stroke="Black"/>
    <Line X1="0" Y1="15" X2="200" Y2="15" StrokeThickness="1" Stroke="Black"/>
</Canvas>

2 つのスニペットの唯一の違いは、最初のスニペットが Line で UseLayoutRounding を使用するのに対して、2 番目のスニペットは Canvas コンテナーで UseLayoutRounding を使用することです (これは、プロパティも Line に継承します)。

しかし、その違いから興味深い結果が得られます。コンテナーで UseLayoutRounding が使用されている場合、1 つのピクセル ラインは一貫して 2 ピクセル以上に広がったままになり、移動しません。ラインで UseLayoutRounding を直接使用し、サイズを変更すると、ラインが 1 ピクセルシャープになることもあれば、2 ピクセル以上広がることもあります。

そして、元の質問のサンプル xaml に行き着きます。それに関するいくつかのコメント:

  1. まず、UseLayoutRounding と SnapsToDevicePixels プロパティの両方が継承されていることに注意してください。つまり、レイアウト コンテナーで使用すると、レイアウト コンテナー内のアイテムに継承されます。
  2. UseLayoutRounding と SnapsToDevicePixels は、必ずしも一緒に使用する必要はありません。それらは可能性があります...しかし、私は通常、それらを別々に使用しようとします...どちらか一方です。詳細はこちら: WPF 4.0 で SnapsToDevicePixels を使用する必要があるのはいつですか?
  3. TextOptions.TextFormattingMode オプションは、行ではなくテキストに影響します。
  4. レイアウト コンテナーとして使用している StackPanel も、行のレイアウト方法に影響を与える可能性があります。キャンバスを使用すると、線の位置をより正確に制御できます。StackPanel は 1 行ずつ別の行にレイアウトするだけで、予期しない結果が生じる可能性があります。

元のポスターが欲しかったものよりも多くの情報。ただし、個人的には、WPF で線をシャープにするのがいかに難しいかを知っています。この情報が誰かの役に立ちますように!

于 2014-12-15T18:07:56.077 に答える
2

Floele の回答は正しい方向性を示していましたが、回答は完全ではありませんでした。y 値を 1/2 ピクセルに設定するだけです。たとえば、Y1="7" -> Y1="7.5" のようになります。

そのため、2 番目と 3 番目の線がぼやけていません。

于 2013-03-15T13:20:52.110 に答える
1

理由は明らかにもっと簡単です。MSDNではなく、「VB 2010のPro WPF」でのみ説明を見つけました:http://books.google.de/books?id=F-gMZkAlUDUC&pg=PA334&lpg=PA334

つまり、 はStrokeThickness形状の両側に分割されるため、aStrokeThicknessが 1 の場合、各辺の太さは 0.5 に等しくなり、線は片側しかないため、0.5 単位の太さになり、 を使用してもぼやけて見えSnapsToDevicePixels=Trueます。したがって、単純に「2」を StrokeThickness として使用します。

4の a を使用してこれを確認できますStrokeThickness。その場合、線の太さは 2 になります。これは、「偶発的な」単一ピクセルのずれよりも大きくなります。

于 2012-01-02T10:46:17.740 に答える
0

TextOptions.TextFormattingModeプロパティをに変更しようとしましたDisplayか? 詳細については、Lester Lobo のこの投稿を参照してください。

于 2009-12-17T01:34:07.173 に答える