mikeo_410


コントロールの動的配置

  コントロールを生成、消滅、移動するものと思っていたら、ContentPresenter クラスを使う例を見たので試してみました。

起動時 追加ボタンを押して行くと

  丸いコントロールが、円周上を移動します。「追加」を押すとコントロールが増えていきます。「削除」を押すとコントロールを1つ削除します。

1.丸いコントロール

  このコントロールは、形状やカラー以外に、自身の表示位置を制御しています。インターバルタイマで、自立的に移動します。
  自身の表示位置は、コントロール自体で決まるものではないので、それが描画されるキャンバスに対する相対的な位置を計算します。このコントロールは、Canvasに対して追加されることを前提にしています。

  1. using System;
  2. using System.Windows;
  3. using System.Windows.Threading;
  4. using System.Windows.Controls;
  5. using System.Windows.Media;
  6. namespace wpf_ContentPresenter1
  7. {
  8.     class MarkCP : ContentPresenter 
  9.     {
  10.         DispatcherTimer timer;
  11.         public MarkCP(Color color)
  12.         {
  13.             Border border = new Border()
  14.             {
  15.                 BorderBrush = new SolidColorBrush(Colors.Black),
  16.                 Background = new SolidColorBrush(color),
  17.                 BorderThickness = new Thickness(2),
  18.                 CornerRadius = new CornerRadius(8),
  19.                 Padding = new Thickness(3)
  20.             };
  21.             Content = border;
  22.             Width = 20;
  23.             Height = 20;
  24.             Round();
  25.             
  26.             timer = new DispatcherTimer() { Interval = new TimeSpan(5000000) };
  27.             timer.Tick += new EventHandler(timer_Tick);
  28.             timer.Start();
  29.         }
  30.         double angle = 0;
  31.         void Round()
  32.         {
  33.             Canvas canvas = (Canvas)Parent;
  34.             if (canvas == null) return;
  35.             double width = canvas.ActualWidth;
  36.             double height = canvas.ActualHeight;
  37.             double r = Math.Min(width, height) * 0.4;
  38.             X = r * Math.Sin(angle) + (width * 0.5);
  39.             Y = r * Math.Cos(angle) + (height * 0.5);
  40.             angle += Math.PI / 24;
  41.         }
  42.         void timer_Tick(object sender, EventArgs e)
  43.         {
  44.             Round();
  45.         }
  46.         double X
  47.         {
  48.             get { return (double)GetValue(Canvas.LeftProperty); }
  49.             set { SetValue(Canvas.LeftProperty, value); }
  50.         }
  51.         double Y
  52.         {
  53.             get { return (double)GetValue(Canvas.TopProperty); }
  54.             set { SetValue(Canvas.TopProperty, value); }
  55.         }
  56.         protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
  57.         {
  58.             base.OnRenderSizeChanged(sizeInfo);
  59.             Round();
  60.         }
  61.     }
  62. }

2.Window1.xaml.cs

  1. using System.Collections.Generic;
  2. using System.Windows;
  3. using System.Windows.Media;
  4. namespace wpf_ContentPresenter1
  5. {
  6.     /// <summary>
  7.     /// Window1.xaml の相互作用ロジック
  8.     /// </summary>
  9.     public partial class Window1 : Window
  10.     {
  11.         public Window1()
  12.         {
  13.             InitializeComponent();
  14.         }
  15.         Stack<MarkCP> stack = new Stack<MarkCP>();
  16.         private void Grid_Loaded(object sender, RoutedEventArgs e)
  17.         {
  18.             MarkCP mcp = new MarkCP(Colors.LightGreen);
  19.             canvas1.Children.Add(mcp);
  20.         }
  21.         Color[] color = new Color[] { Colors.LightPink, Colors.Yellow, Colors.LightBlue, Colors.Magenta };
  22.         private void Button_Click_add(object sender, RoutedEventArgs e)
  23.         {
  24.             MarkCP mcp = new MarkCP(color[stack.Count%color.Length]);
  25.             stack.Push(mcp);
  26.             canvas1.Children.Add(mcp);
  27.         }
  28.         private void Button_Click_delete(object sender, RoutedEventArgs e)
  29.         {
  30.             if (stack.Count <= 0) return;
  31.             MarkCP mcp = stack.Pop();
  32.             canvas1.Children.Remove(mcp);
  33.         }
  34.     }
  35. }

3.Window1.xaml

  1. <Window x:Class="wpf_ContentPresenter1.Window1"
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.     Title="動的な配置" Width="300" Height="300">
  5.     <Grid  Loaded="Grid_Loaded">
  6.         <Grid.RowDefinitions>
  7.             <RowDefinition Height="20"/>
  8.             <RowDefinition/>
  9.         </Grid.RowDefinitions>
  10.         <Grid Grid.Row="0">
  11.             <Grid.ColumnDefinitions>
  12.                 <ColumnDefinition/>
  13.                 <ColumnDefinition/>
  14.             </Grid.ColumnDefinitions>
  15.             <Button Grid.Column="0" Content="追加" Click="Button_Click_add"/>
  16.             <Button Grid.Column="1" Content="削除" Click="Button_Click_delete"/>
  17.         </Grid>
  18.         <Canvas Grid.Row="1" x:Name="canvas1">        
  19.         </Canvas>
  20.     </Grid>
  21. </Window>


mikeo_410@hotmail.com