WPF 自定义属性

  做了一个自定义控件和一个自定义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

原文地址:https://www.cnblogs.com/sshoub/p/3236691.html