前回に引き続き、さらに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