WPF_CustomControl之拥有Visible属性的ColumnDefinition或者RowDefinition

WPF_CustomControl之拥有Visible属性的ColumnDefinition或者RowDefinition

一、背景

在WPF中布局的时候我们会经常用到ColumnDefinition,但是这个控件没有Visible属性,用来控制ColumnDefinition控件是否显示。

二、思路

ColumnDefinition控件本身是没有Visible属性的,所以我们需要自定义一个控件,这个控件继承ColumnDefinition,然后需要自定义一个bool类型的依赖属性Visible。

Visible属性的默认值为true;当Visible设置为false的时候,需要把Width属性设置为零,同时还需要把MinWidth属性也设置为零。这里有一个细节需要注意,但设置Width值的时候,实际设置的值会是Width和MinWidth值的最小值。所以Width属性设置为零的同时还需要把MinWidth属性也设置为零;当Visible设置为true的时候,那么Width值和MinWidth值设置为其对应的值就行。

三、实现

1、首先在WPF中创建自定义控件,会生成一个cs文件,然后修改父类为ColumnDefinition

public class ColumnDefinitionExtended : System.Windows.Controls.ColumnDefinition
    {

        static ColumnDefinitionExtended()
        {

        }
    }

2、注册一个bool类型的依赖属性

public bool Visible
        {
            get { return (bool)GetValue(VisibleProperty); }
            set { SetValue(VisibleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Visible.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty VisibleProperty =
            DependencyProperty.Register("Visible", typeof(bool), typeof(ColumnDefinitionExtended),
                new PropertyMetadata(true, new PropertyChangedCallback(OnVisibleChanged)));

        private static void OnVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

注册依赖属性的时候PropertyMetadata类型的参数使用有回调函数的那一个。表示当改变Visible属性的时候会被触发。通过上面的分析思路,我们应该要在回调函数里进行校验,校验Width属性和MinWidth属性的值,所以我们需要提供校验函数。

3、注册Width和MinWidth的校验函数

static ColumnDefinitionExtended()
        {
            WidthProperty.OverrideMetadata(typeof(ColumnDefinitionExtended),
                new FrameworkPropertyMetadata(new GridLength(0), null, new CoerceValueCallback(CoerceWidth)));
            MinWidthProperty.OverrideMetadata(typeof(ColumnDefinitionExtended),
                new FrameworkPropertyMetadata((double)0, null, new CoerceValueCallback(CoerceMinWidth)));
        }

校验函数的实现:

private static object CoerceMinWidth(DependencyObject d, object baseValue)
        {
            return ((ColumnDefinitionExtended)d).Visible ? baseValue : (Double)0;
        }

        private static object CoerceWidth(DependencyObject d, object baseValue)
        {
            return ((ColumnDefinitionExtended)d).Visible ? baseValue : new GridLength(0);
        }

4、调用校验函数

private static void OnVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            d.CoerceValue(ColumnDefinition.WidthProperty);
            d.CoerceValue(ColumnDefinition.MinWidthProperty);
        }

5、完整cs文件代码

 public class ColumnDefinitionExtended : ColumnDefinition
    {

        static ColumnDefinitionExtended()
        {
            WidthProperty.OverrideMetadata(typeof(ColumnDefinitionExtended),
                new FrameworkPropertyMetadata(new GridLength(0), null, new CoerceValueCallback(CoerceWidth)));
            MinWidthProperty.OverrideMetadata(typeof(ColumnDefinitionExtended),
                new FrameworkPropertyMetadata((double)0, null, new CoerceValueCallback(CoerceMinWidth)));
        }

        private static object CoerceMinWidth(DependencyObject d, object baseValue)
        {
            return ((ColumnDefinitionExtended)d).Visible ? baseValue : (Double)0;
        }

        private static object CoerceWidth(DependencyObject d, object baseValue)
        {
            return ((ColumnDefinitionExtended)d).Visible ? baseValue : new GridLength(0);
        }

        public bool Visible
        {
            get { return (bool)GetValue(VisibleProperty); }
            set { SetValue(VisibleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Visible.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty VisibleProperty =
            DependencyProperty.Register("Visible", typeof(bool), typeof(ColumnDefinitionExtended),
                new PropertyMetadata(true, new PropertyChangedCallback(OnVisibleChanged)));

        private static void OnVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            d.CoerceValue(WidthProperty);
            d.CoerceValue(MinWidthProperty);
        }
    }

6、自定义的RowDefinition控件类似。

四、使用

1、在xaml文件中导入命令空间。例:

xmlns:cle="clr-namespace:ColumnDefinitionTest"

2、在Grid.ColumnDefinitions中使用。列:

<Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <cle:ColumnDefinitionExtended Visible="{Binding ElementName=ck, Path=IsChecked}" Width="{Binding ElementName=slider, Path=Value}" MinWidth="50" MaxWidth="800" x:Name="Cde"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

五、效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值