Quantcast
Channel: 午後わてんのブログ
Viewing all articles
Browse latest Browse all 420

EdgeModeでアンチエイリアスの有無を切り替え、WPF

$
0
0

RenderOptions.SetEdgeModeで図形のアンチエイリアスの有無を切り替え
イメージ 1
左右それぞれのStackPanelの下の方に表示している図形は上から
Line(太さ0.5)
Line(太さ1.0)
Line(太さ5.0)Lineはそれぞれ2本ずつ
Rectangle
Ellipse
右のすべての図形は図形自体のEdgeModeにAliasedを指定している
左は指定なし
この状態からボタンでStackPanelのEdgeModeを切り替えてしている

EdgeMode
指定できるのは2種類でUnspecifiedとAliased
Unspecifiedは日本語で未定義、不特定の意味らしい
特に指定しない場合はこれになるみたいで結果はアンチエイリアスが有効な状態
Aliasedを指定するとアンチエイリアスが無効になる
親要素にAliasedを指定すると所属している子要素すべてもアンチエイリアス無効になる

UseLayoutRounding
これはおまけで試してみた、切り替えると表示位置が微妙に移動する
有効にすると表示位置をピクセルに合わせてくれる感じなのかなあ、よくわからん

SnapsToDevicePixels
切り替えても何も変化しないねえ



今回のVBコード

Class MainWindow
Private MyRect As Path

Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
'Mode変更のボタン追加
Call AddEdgeModeButton(MyStackP1)
Call AddEdgeModeButton(MyStackP2)
Call AddUselayoutRoundingButton(MyStackP1)
Call AddUselayoutRoundingButton(MyStackP2)
Call AddSnapsToDevicePixelsButton(MyStackP1)
Call AddSnapsToDevicePixelsButton(MyStackP2)
'Mode表示用のTextBlock追加
Call AddTextBlock(MyStackP1)
Call AddTextBlock(MyStackP2)

'EdgeMode = Unspecified(初期設定)のLineを左のStackPanelに追加
With MyStackP1.Children
.Add(CreateLine(0.5, False)) '数値は線の太さ
.Add(CreateLine(0.5, False))
.Add(CreateLine(1.0, False))
.Add(CreateLine(1.0, False))
.Add(CreateLine(5.0, False))
.Add(CreateLine(5.0, False))
.Add(CreateRectangle(False))
.Add(CreateEllipse(False))
End With

'EdgeMode = AliasedのLineを右のStackPanelに追加
With MyStackP2.Children
.Add(CreateLine(0.5, True))
.Add(CreateLine(0.5, True))
.Add(CreateLine(1.0, True))
.Add(CreateLine(1.0, True))
.Add(CreateLine(5.0, True))
.Add(CreateLine(5.0, True))
.Add(CreateRectangle(True))
.Add(CreateEllipse(True))
End With

End Sub

'図形作成
'Line作成
Private Function CreateLine(bold As Double, a As Boolean) As Line
Dim l As New Line
With l
.Stroke = Brushes.Black
.StrokeThickness = bold
.X1 = 0 : .X2 = 150 : .Y1 = 0 : .Y2 = 10
End With
If a Then
RenderOptions.SetEdgeMode(l, EdgeMode.Aliased)
End If
Return l
End Function
'Rectangle
Private Function CreateRectangle(a As Boolean) As Rectangle
Dim r As New Rectangle With {.Width = 50, .Height = 50,
.Fill = Brushes.Black}
If a Then RenderOptions.SetEdgeMode(r, EdgeMode.Aliased)
Return r
End Function
'Ellipse
Private Function CreateEllipse(a As Boolean) As Ellipse
Dim el As New Ellipse With {.Width = 50, .Height = 50,
.Fill = Brushes.Black}
If a Then RenderOptions.SetEdgeMode(el, EdgeMode.Aliased)
Return el
End Function

'ボタン作成
'EdgeMode切り替えボタン作成
Private Sub AddEdgeModeButton(p As StackPanel)
Dim b As New Button With {.Content = "EdgeMode変更",
.Margin = New Thickness(2)}
p.Children.Add(b)
'ボタンクリックイベントにくっつける
AddHandler b.Click, AddressOf ChangeEdgeMode
End Sub
'UseLayoutRounding変更ボタン作成
Private Sub AddUselayoutRoundingButton(p As StackPanel)
Dim b As New Button With {.Content = "UseLayoutRounding変更",
.Margin = New Thickness(2)}
p.Children.Add(b)
AddHandler b.Click, AddressOf ChangeUseLayoutRounding
End Sub
'SnapsToDevicePixels変更ボタン作成
Private Sub AddSnapsToDevicePixelsButton(p As StackPanel)
Dim b As New Button With {.Content = "SnapsToDevicePixels変更",
.Margin = New Thickness(2)}
p.Children.Add(b)
AddHandler b.Click, AddressOf ChangeSnapsToDevicePixels
End Sub


'ボタンクリックイベント用
'親パネルのRenderOptions.EdgeModeを切り替える
Private Sub ChangeEdgeMode(sender As Object, e As RoutedEventArgs)
Dim p As StackPanel = DirectCast(sender.parent, StackPanel)
If RenderOptions.GetEdgeMode(p) = EdgeMode.Aliased Then
RenderOptions.SetEdgeMode(p, EdgeMode.Unspecified)
Else
RenderOptions.SetEdgeMode(p, EdgeMode.Aliased)
End If
End Sub
'親パネルのUseLayoutRoundingを切り替える
Private Sub ChangeUseLayoutRounding(sender As Object, e As RoutedEventArgs)
Dim p As StackPanel = DirectCast(sender.parent, StackPanel)
p.UseLayoutRounding = Not p.UseLayoutRounding
End Sub
'親パネルのSnapsToDevicePixelsを切り替える
Private Sub ChangeSnapsToDevicePixels(sender As Object, e As RoutedEventArgs)
Dim p As StackPanel = DirectCast(sender.parent, StackPanel)
p.SnapsToDevicePixels = Not p.SnapsToDevicePixels
End Sub




'Mode表示用TextBlock作成
Private Sub AddTextBlock(p As StackPanel)
'Bindingソース作成、StackPanelのEdgeModePropertyをソースにする
Dim b As New Binding With {
.Source = p,
.Path = New PropertyPath(RenderOptions.EdgeModeProperty),
.StringFormat = "PanelのEdgeMode = {0}"
}

Dim tb As New TextBlock
'TextBlockのTextPropertyにBinding
tb.SetBinding(TextBlock.TextProperty, b)
p.Children.Add(tb)

'UseLayoutRounding表示用TextBlock
tb = New TextBlock
b = New Binding With {
.Source = p,
.Path = New PropertyPath(StackPanel.UseLayoutRoundingProperty),
.StringFormat = "PanelのUseLayoutRounding = {0}"}
tb.SetBinding(TextBlock.TextProperty, b)
p.Children.Add(tb)

'SnapToDevicePixels表示用TextBlock
tb = New TextBlock
b = New Binding With {
.Source = p,
.Path = New PropertyPath(StackPanel.SnapsToDevicePixelsProperty),
.StringFormat = "PanelのSnapToDevicePixels = {0}"}
tb.SetBinding(TextBlock.TextProperty, b)
p.Children.Add(tb)
End Sub
End Class

XAMLデザインモード
イメージ 2




参照したところ

WPFでアンチエイリアシングを無効にする方法 – 川西 裕幸のブログ
https://blogs.msdn.microsoft.com/hiroyuk/2009/02/15/wpf-2/

WPFでのUIアンチエイリアス封じ込め - コンクリートアスパラガス
http://d.hatena.ne.jp/Conpara02/20120526/1338017590

MahAppsのTreeViewをWPFで使ったときの話 - PG日誌
http://takachan.hatenablog.com/entry/2016/01/06/231255

【WPF】グリッド状の模様を描く (1)~(6)のまとめ – ザワプロ!
http://zawapro.com/?p=1041

.NET TIPS: WPF/ UWP: コントロールのエッジをシャープに描画するには?[XAML] - @IT
http://www.atmarkit.co.jp/ait/articles/1602/17/news034.html

文字列をフォーマットして表示するはなし with 多言語対応とかマークアップ拡張とか - Qiita
http://qiita.com/wonderful_panda/items/a45ffaaca7f9c6e0d494
ありがとうございます!



この前の記事の
WPF、BindingのStringFormat、数値の書式設定をVBコードで ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/14895536.html
これに付け足し

TextBlockにBindingする値が文字列でその文字列に別の文字列を追加して表示したいとき
今回のだとこれ、EdgeModeをTextBlockにBindingして表示する
'Bindingソース作成、StackPanelのEdgeModePropertyをソースにする
Dim b As New Binding With {
.Source = p,
.Path = New PropertyPath(RenderOptions.EdgeModeProperty),
.StringFormat = "PanelのEdgeMode = {0}"
}

EdgeModeがAliasedのとき
BindingのStringFormatに何も指定しないと表示されるのはAliased
PanelのEdgeMode  = Aliasedって表示したいときは上のように
.StringFormat = "PanelのEdgeMode = {0}"
って書けばいいみたい、{0}ってところにBindingした値が表示される





Viewing all articles
Browse latest Browse all 420

Trending Articles