前回に引き続き、さらにWPFでグリッド状の模様を描く方法について考えてみる。
今回は、LineGeometryを持たせたPathでグリッド状の模様を描くことにした。
まず、MainWindowのxamlを示す。
<Window x:Class="WpfPathGeometryLesson.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition Height="24"></RowDefinition> </Grid.RowDefinitions> <Canvas Name="canvas" SnapsToDevicePixels="True" Loaded="canvas_Loaded" SizeChanged="canvas_SizeChanged"> </Canvas> <Slider Grid.Row="1" Name="slider" Minimum="1" Maximum="4" TickFrequency="0.1"></Slider> </Grid> </Window>
グリッド模様を描くためのCanvasと、表示倍率を変更するためのスライダーを上下に配置している。
11行目でCanvasのSnapToDevicePixelsをTrueにセットしている。この値をTrueにすると、後で描くグリッドの線がぼやけず、くっきりと表示されるようになった。
スライダーの値はPathのScaleTransformにバインディングするのだが、それはC#で行う。
それでは、次にC#のコードを示す。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfPathGeometryLesson { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { private const int GRID_SIZE = 10; private ScaleTransform scaleTransform = new ScaleTransform(); public MainWindow() { InitializeComponent(); // ScaleTransformのScaleXにスライダーの値をバインディング BindingOperations.SetBinding( scaleTransform, ScaleTransform.ScaleXProperty, new Binding("Value") { Source = slider }); // ScaleTransformのScaleYにスライダーの値をバインディング BindingOperations.SetBinding( scaleTransform, ScaleTransform.ScaleYProperty, new Binding("Value") { Source = slider }); } private void canvas_Loaded(object sender, RoutedEventArgs e) { BuildView(); } private void canvas_SizeChanged(object sender, SizeChangedEventArgs e) { BuildView(); } // グリッド模様の構築 private void BuildView() { canvas.Children.Clear(); // 縦線 for (int i = 0; i < canvas.ActualWidth; i += GRID_SIZE) { Path path = new Path() { Data = new LineGeometry(new Point(i, 0), new Point(i, canvas.ActualHeight)), Stroke = Brushes.Aqua, StrokeThickness = 1 }; path.Data.Transform = scaleTransform; canvas.Children.Add(path); } // 横線 for (int i = 0; i < canvas.ActualHeight; i += GRID_SIZE) { Path path = new Path() { Data = new LineGeometry(new Point(0,i), new Point(canvas.ActualWidth,i)), Stroke = Brushes.Aqua, StrokeThickness = 1 }; path.Data.Transform = scaleTransform; canvas.Children.Add(path); } } } }
コンストラクタの29-38行目でScaleTransformのScaleXとScaleYにスライダーの値をバインディングしている。
あえてコードでバインディングしているのは、このScaleTransformを、後で動的に作るLineGeometryのTransformにセットしたいからである。こういったケースではxamlだけでなく、C#のコーディングが必要になってくる。
51-81行目のメソッドでグリッド模様を構築している。このメソッドはCanvasのロード時とリサイズ時に呼ばれる。
グリッド模様を描くのに必要な線の数だけLineGeometryを持ったPathを作成し、CanvasのChildrenに追加している。
このプログラムを実行すると以下のように表示される。
スライダーを動かすと、その値がPath内のLineGeometryのScaleTransformの値に連動し、模様のサイズが変わる。
このアプリを、速い速度でリサイズしてみたのだが、画面表示は乱れなかった。
グリッド状の模様を描くには、この方法がベストかもしれない。
ピンバック: 【WPF】グリッド状の模様を描く その(6)WindowsFormsHostを使う – ザワプロ!
ピンバック: VisualC# Thumbオブジェクトを再描画させたい – Code Fix