Custom ReadOnlyProperty【PluraSight】
Limited functionality:
- Not settable
- No data binding
- No validation
- No animation
- No Inheritance
When to use?
- Used for state determination(Defined the style for the control, some visiable property like fore/background will change when mouse movehover)
- Used as a property trigger(由这个readonly property change,来change control's states)
要求: 我们有一个button,和一个read-only property来track button is been clicked的状态,如果被clicked的话,这个property变为true,我们change button的background
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace CustomControlLib { public class MyCustomControl : Control { static MyCustomControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl))); } private static readonly DependencyPropertyKey HasBeenClickedPropertyKey = DependencyProperty.RegisterReadOnly("HasBeenClicked", typeof(bool), typeof(MyCustomControl), new PropertyMetadata(false)); public static readonly DependencyProperty HasBeenClickedProperty = HasBeenClickedPropertyKey.DependencyProperty; //When you create the DependencyPropertyKey it will automaticly create the DependencyProperty for you public bool HasBeenClicked //注意这里的wrapper的名字要和register时给的""里的名字一致 { get { return (bool)GetValue(HasBeenClickedProperty); } //因为做的是 readonly property,所以只有getter } public override void OnApplyTemplate() //override OnApplyTemplate { base.OnApplyTemplate(); //demo purposes only, check for previous instances and remove handler first var button = GetTemplateChild("PART_Button") as Button; //call 前台的x:Name if (button != null) button.Click += Button_Click; //hock OnApplyTemplate() 去instantiate 一个按钮被点击的Event Handler } void Button_Click(object sender, RoutedEventArgs e) { SetValue(HasBeenClickedPropertyKey, true); //其他继承类若要用这个DependencyPropertyKey,吧private改成protect或者internal //接下来要做的事当这个button被按后我们要set HasBeenClicked(ReadOnly) //不可以set HasBeenClicked只可以用SetValue找HasBeenClickedPropertyKey } } }
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CustomControlLib"> <Style TargetType="{x:Type local:MyCustomControl}"> <Setter Property="Margin" Value="50" /> <Setter Property="Background" Value="Gray" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:MyCustomControl}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Button x:Name="PART_Button" Background="{TemplateBinding Background}" Content="Click Me" /> </Border> <ControlTemplate.Triggers> <Trigger Property="HasBeenClicked" Value="true"> <Setter Property="Background" Value="Green" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
<Window x:Class="CustomControlDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cc="clr-namespace:CustomControlLib;assembly=CustomControlLib" Title="MainWindow" Height="350" Width="525"> <Grid> <cc:MyCustomControl /> </Grid> </Window>