做了一个自定义控件和一个自定义Grid,里面的元素可以随着绑定属性变化:
效果图(一定滑块):
关键代码:
1、自定义属性代码:
public class MyGrid : Grid { public static readonly DependencyProperty ColumnCountProperty = DependencyProperty.Register("ColumnCount", typeof(int), typeof(MyGrid), new FrameworkPropertyMetadata((int)1,FrameworkPropertyMetadataOptions.AffectsRender,null,new CoerceValueCallback(CoerceColumnCount))); public int ColumnCount { get { return (int)GetValue(ColumnCountProperty); } set { SetValue(ColumnCountProperty, value); } } private static object CoerceColumnCount(DependencyObject element, object value) { int input = (int)value; if (input < 1) { return 1; } else { return input; } } protected override void OnRender(System.Windows.Media.DrawingContext dc) { base.OnRender(dc); //获得现有行数、列数 int columnCount = this.ColumnDefinitions.Count; int rowCount = this.RowDefinitions.Count; //不变化,则不处理 if (this.ColumnDefinitions.Count == this.ColumnCount) return; //获得最后一个元素的数量 int elementCount = 0; for (int i = this.Children.Count - 1; i >= 0; i--) { UIElement element = this.Children[i]; int row = Grid.GetRow(element); int column = Grid.GetColumn(element); int num = row * columnCount + column + 1; if (num > elementCount) { elementCount = num; } } //大于最大数,直接返回 if (this.ColumnCount > elementCount) return; //计算新行列 int newRowCount = (int)Math.Ceiling((double)elementCount / this.ColumnCount); int newColumnCount = this.ColumnCount; this.RowDefinitions.Clear(); this.ColumnDefinitions.Clear(); for (int i = 0; i < newRowCount; i++) { RowDefinition rd = new RowDefinition(); this.RowDefinitions.Add(rd); } for (int i = 0; i < newColumnCount; i++) { ColumnDefinition cd = new ColumnDefinition(); this.ColumnDefinitions.Add(cd); } //添加元素 foreach (UIElement element in this.Children) { int row = Grid.GetRow(element); int column = Grid.GetColumn(element); int allCount = row * columnCount + column; int newRow = allCount / newColumnCount; int newColumn = allCount % newColumnCount; Grid.SetRow(element, newRow); Grid.SetColumn(element, newColumn); } } }
里面有两个地方需要注意:
1、依赖属性一定要设定为 static ,要不然在XAML中引用的时候出现异常,VS直接卡死;
2、在OnRender函数中,一定要尽量少的执行代码,因为这个方法一直在异步刷新;
用到的算法:
进制的转化思想:先计算出一种进制的十进制,再转换为别的进制。
例子下载:Code