WPF 只读附加属性的赋值与绑定
附加只读属性是通过获取非公开的DependencyPropertyKey字段的DependencyProperty属性。
internal static readonly DependencyPropertyKey ClickCountReadOnlyPropertyKey = DependencyProperty.RegisterAttachedReadOnly("ClickCountReadOnly", typeof(int), typeof(CheckBoxAttch), new PropertyMetadata(0)); public static readonly DependencyProperty ClickCountReadOnlyProperty = ClickCountReadOnlyPropertyKey.DependencyProperty; public static int GetClickCountReadOnly(DependencyObject dependencyObject) { return (int)dependencyObject.GetValue(ClickCountReadOnlyProperty); }
因为是附加属性,所有包装器是以方法的形式存在。
其中,在注册只读属性时注册名要与公开的附加属性,公开方法一致,符合约定。
附加属性是可读,可写。附加只读属性是不可写入。
当然这是有条件的,在外部获取,在拿不到非公开的dependency property key时是不可写入。换句说,如果想要赋值必须通过非公开的只读key。
以下列代码为例子
假定检测一个点击checkbox的数与是否选择有关。
点击数 1 是选择
点击数 2 是非选择
点击数 0 是默认值
xaml:
<StackPanel> <CheckBox VerticalContentAlignment="Center" Content="{Binding ElementName=tb1, Path=Text}" ContentStringFormat="Click:{0}" x:Name="cb1" FontSize="55" VerticalAlignment="Top" local:CheckBoxAttch.AutoCount="True"/> <CheckBox VerticalContentAlignment="Center" Content="{Binding ElementName=tb2, Path=Text}" ContentStringFormat="Click:{0}" x:Name="cb2" FontSize="55" VerticalAlignment="Top" local:CheckBoxAttch.AutoCount="True"/> <TextBlock x:Name="tb1" VerticalAlignment="Top" HorizontalAlignment="Right" Text="{Binding ElementName=cb1, Path=(local:CheckBoxAttch.ClickCountReadOnly)}"/> <TextBlock x:Name="tb2" VerticalAlignment="Top" HorizontalAlignment="Right" Text="{Binding ElementName=cb2, Path=(local:CheckBoxAttch.ClickCountReadOnly)}"/> </StackPanel>
code:
class CheckBoxAttch { public static bool GetAutoCount(DependencyObject obj) { return (bool)obj.GetValue(AutoCountProperty); } public static void SetAutoCount(DependencyObject obj, bool value) { obj.SetValue(AutoCountProperty, value); } public static readonly DependencyProperty AutoCountProperty = DependencyProperty.RegisterAttached("AutoCount", typeof(bool), typeof(CheckBoxAttch), new PropertyMetadata(false, new PropertyChangedCallback(OnAutoValueChanged))); private static void OnAutoValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is CheckBox box) { if ((bool)e.NewValue) { box.PreviewMouseLeftButtonUp -= Picker_PreviewMouseDown; box.PreviewMouseLeftButtonUp += Picker_PreviewMouseDown; } else { box.PreviewMouseLeftButtonDown -= Picker_PreviewMouseDown; } } } private static void Picker_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { var box = (CheckBox)sender; var count = (int)box.GetValue(ClickCountReadOnlyProperty); if (box.IsChecked.HasValue) { if (count != 1) { box.SetValue(ClickCountReadOnlyPropertyKey, 1); } else { if (count == 1) { box.SetValue(ClickCountReadOnlyPropertyKey, 2); } } } } internal static readonly DependencyPropertyKey ClickCountReadOnlyPropertyKey = DependencyProperty.RegisterAttachedReadOnly("ClickCountReadOnly", typeof(int), typeof(CheckBoxAttch), new PropertyMetadata(0)); public static readonly DependencyProperty ClickCountReadOnlyProperty = ClickCountReadOnlyPropertyKey.DependencyProperty; public static int GetClickCountReadOnly(DependencyObject dependencyObject) { return (int)dependencyObject.GetValue(ClickCountReadOnlyProperty); } }
我们注意到在xaml ,绑定其他控件的附加属性是通过()转换得到。
在code中 我们也是用过key去setvalue,并非通过附加属性。