WPFのColumnsGrid

グリッドコントロールにアイテムを配置するのは面倒です。 UniformGridのように、セルに自動的に配置する方が便利です。



ColumnsGridは、これに次の機能を追加します。



  1. 列は単一行として定義されますColumns = "Auto、*、200、Shared1"
  2. 列間の間隔を設定します。
  3. 次の行への遷移は、要素<Separator Height = "4" />によって設定されます


using System; using System.Windows; using System.Windows.Controls; public class ColumnsGrid : Grid { public ColumnsGrid() : base() { ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto }); RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); }
      
      





間隔プロパティ
 public double Spacing { get { return (double)GetValue(SpacingProperty); } set { SetValue(SpacingProperty, value); } } public static readonly DependencyProperty SpacingProperty = DependencyProperty.Register("Spacing", typeof(double), typeof(ColumnsGrid), new FrameworkPropertyMetadata(0.0, SpacingChangedCallback)); static void SpacingChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((ColumnsGrid)d).SpacingChanged((double)e.NewValue); }
      
      







  void SpacingChanged(double value) { bool even = true; var l = new GridLength(Spacing); foreach (var cd in ColumnDefinitions) { if (!even) cd.Width = l; even = !even; } }
      
      





Columnsプロパティ
 public string Columns{ get { return (string)GetValue(ColumnsProperty); } set { SetValue(ColumnsProperty, value); } } public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", typeof(string), typeof(ColumnsGrid), new FrameworkPropertyMetadata("Auto", ColumnsChangedCallback)); static void ColumnsChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((ColumnsGrid)d).ColumnsChanged((double)e.NewValue); }
      
      







  void ColumnsChanged(string value) { var ss = value.Split(','); ColumnDefinitions.Clear(); var cnv = new GridLengthConverter(); foreach (var s in ss) { var cd = new ColumnDefinition(); try { cd.Width = (GridLength)cnv.ConvertFromInvariantString(s.Trim()); } catch { cd.Width = GridLength.Auto; cd.SharedSizeGroup = s; } if (ColumnDefinitions.Count>0) ColumnDefinitions.Add( new ColumnDefinition() { Width = new GridLength(Spacing) }); ColumnDefinitions.Add(cd); } if (ColumnDefinitions.Count==0) ColumnDefinitions.Add( new ColumnDefinition() { Width = GridLength.Auto }); InvokeArrange(); } protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved) { base.OnVisualChildrenChanged(visualAdded, visualRemoved); InvokeArrange(); } bool ArrangeInvoked; void InvokeArrange() { if (ArrangeInvoked) return; ArrangeInvoked = true; Application.Current.Dispatcher.BeginInvoke(new Action(Arrange)); } void Arrange() { ArrangeInvoked = false; RowDefinitions.Clear(); RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); int row = 0, col = 0; foreach (UIElement child in InternalChildren) { if (child is Separator) { child.Visibility = Visibility.Hidden; col = 0; row++; RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); SetColumn(child, 0); SetRow(child, row); row++; RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); } else { SetColumn(child, col); SetRow(child, row); col += 2; } } } }
      
      





このテーマに関するHabréの出版物:



XAML開発者チップ:動的グリッド



All Articles