WPF

    科技2024-09-30  30

    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>

    五、效果

    Processed: 0.016, SQL: 8