コントロールの動的配置
コントロールを生成、消滅、移動するものと思っていたら、ContentPresenter クラスを使う例を見たので試してみました。
起動時 |
追加ボタンを押して行くと |
|
|
丸いコントロールが、円周上を移動します。「追加」を押すとコントロールが増えていきます。「削除」を押すとコントロールを1つ削除します。
1.丸いコントロール
このコントロールは、形状やカラー以外に、自身の表示位置を制御しています。インターバルタイマで、自立的に移動します。
自身の表示位置は、コントロール自体で決まるものではないので、それが描画されるキャンバスに対する相対的な位置を計算します。このコントロールは、Canvasに対して追加されることを前提にしています。
- using System;
- using System.Windows;
- using System.Windows.Threading;
- using System.Windows.Controls;
- using System.Windows.Media;
- namespace wpf_ContentPresenter1
- {
- class MarkCP : ContentPresenter
- {
- DispatcherTimer timer;
- public MarkCP(Color color)
- {
- Border border = new Border()
- {
- BorderBrush = new SolidColorBrush(Colors.Black),
- Background = new SolidColorBrush(color),
- BorderThickness = new Thickness(2),
- CornerRadius = new CornerRadius(8),
- Padding = new Thickness(3)
- };
- Content = border;
- Width = 20;
- Height = 20;
- Round();
-
- timer = new DispatcherTimer() { Interval = new TimeSpan(5000000) };
- timer.Tick += new EventHandler(timer_Tick);
- timer.Start();
- }
- double angle = 0;
- void Round()
- {
- Canvas canvas = (Canvas)Parent;
- if (canvas == null) return;
- double width = canvas.ActualWidth;
- double height = canvas.ActualHeight;
- double r = Math.Min(width, height) * 0.4;
- X = r * Math.Sin(angle) + (width * 0.5);
- Y = r * Math.Cos(angle) + (height * 0.5);
- angle += Math.PI / 24;
- }
- void timer_Tick(object sender, EventArgs e)
- {
- Round();
- }
- double X
- {
- get { return (double)GetValue(Canvas.LeftProperty); }
- set { SetValue(Canvas.LeftProperty, value); }
- }
- double Y
- {
- get { return (double)GetValue(Canvas.TopProperty); }
- set { SetValue(Canvas.TopProperty, value); }
- }
- protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
- {
- base.OnRenderSizeChanged(sizeInfo);
- Round();
- }
- }
- }
2.Window1.xaml.cs
- using System.Collections.Generic;
- using System.Windows;
- using System.Windows.Media;
- namespace wpf_ContentPresenter1
- {
- /// <summary>
- /// Window1.xaml の相互作用ロジック
- /// </summary>
- public partial class Window1 : Window
- {
- public Window1()
- {
- InitializeComponent();
- }
- Stack<MarkCP> stack = new Stack<MarkCP>();
- private void Grid_Loaded(object sender, RoutedEventArgs e)
- {
- MarkCP mcp = new MarkCP(Colors.LightGreen);
- canvas1.Children.Add(mcp);
- }
- Color[] color = new Color[] { Colors.LightPink, Colors.Yellow, Colors.LightBlue, Colors.Magenta };
- private void Button_Click_add(object sender, RoutedEventArgs e)
- {
- MarkCP mcp = new MarkCP(color[stack.Count%color.Length]);
- stack.Push(mcp);
- canvas1.Children.Add(mcp);
- }
- private void Button_Click_delete(object sender, RoutedEventArgs e)
- {
- if (stack.Count <= 0) return;
- MarkCP mcp = stack.Pop();
- canvas1.Children.Remove(mcp);
- }
- }
- }
3.Window1.xaml
- <Window x:Class="wpf_ContentPresenter1.Window1"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="動的な配置" Width="300" Height="300">
- <Grid Loaded="Grid_Loaded">
- <Grid.RowDefinitions>
- <RowDefinition Height="20"/>
- <RowDefinition/>
- </Grid.RowDefinitions>
- <Grid Grid.Row="0">
- <Grid.ColumnDefinitions>
- <ColumnDefinition/>
- <ColumnDefinition/>
- </Grid.ColumnDefinitions>
- <Button Grid.Column="0" Content="追加" Click="Button_Click_add"/>
- <Button Grid.Column="1" Content="削除" Click="Button_Click_delete"/>
- </Grid>
- <Canvas Grid.Row="1" x:Name="canvas1">
- </Canvas>
- </Grid>
- </Window>
|