一~七
八.DependencyProperty
1.介绍
我们经常遇到的一个情况是某个属性的值的变化会影响到多个其他对象。比如当一个Button的改变大小超过了它的容器,他的容器应该自动调整大小。这时候就可以用到DependencyProperty。
DependencyProperty属性和普通的属性相比最大不同在于,它的值的来源并不单一。对这种属性的取值和赋值都会能与其他对象有影响,因此能得到很大的灵活性。
public static readonly DependencyProperty MyStringProperty = DependencyProperty.Register(
"MyString",
typeof(string),
typeof(ClassMyDependency),
new PropertyMetadata("defaultValue", new PropertyChangedCallback(onMyStringPropertyChange)));
通常会用DependencyProperty类的静态方法Register方法创建。 Register方法需要以下参数:
第一个参数MyString代表的是该属性的名称,能够通过注册找到该字句,但是实际中发现不需要为MyString也能操作成功,测试中将其改为q。在实际的测试中发现
Text="{Binding ElementName=test11,
Path=MyString,
UpdateSourceTrigger=PropertyChanged}"
Text="{Binding ElementName=test11,
Path=q,
UpdateSourceTrigger=PropertyChanged}"两者效果一致。
第二个参数typeof(string)代表的是该属性的类型
第三个参数typeof(UserControl1)代表的是该属性所有者的类型
第四个参数 new PropertyMetadata(“defaultValue”, new PropertyChangedCallback(OnMyStringPropertyChange))代表的是属性元数据注册依赖项属性。这些元数据可以决定属性如何被WPF对待,是否当属性值改变时进行回调,强制限定属性值或者验证属性值。 这里就是封装属性的相关操作的。
当需要访问属性的值时,只需要调用对象的GetValue()和SetValue()方法来访问()。可以转变成我们习惯的样子。
public string MyString
{
get{return (string)GetValue(MyStringProperty);}
set{SetValue(MyStringProperty,value;}
}
2.实例
建立一个有DependencyProperty修饰的界面
<UserControl x:Class="test1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBox Name="textBox1" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" VerticalAlignment="Top" Width="120" TextChanged="OnTextChanged" />
</Grid>
</UserControl>
namespace test1
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
//private string _myString;
public string MyString
{
get { return (string)GetValue(MyStringProperty); }
//set { _myString = value; textBox1.Text = _myString; }
set { SetValue(MyStringProperty, value); }
}
public static readonly DependencyProperty MyStringProperty = DependencyProperty.Register("MyString", typeof(string),
typeof(UserControl1), new PropertyMetadata("defaultValue", new PropertyChangedCallback(OnMyStringPropertyChange)));
static void OnMyStringPropertyChange(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
UserControl1 source = (UserControl1)sender;
source.textBox1.Text = args.NewValue.ToString() + args.NewValue.ToString().Length.ToString();
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
//UserControl1.OnMyStringPropertyChange(sender,)
}
}
}
主页面
<Window x:Class="test1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:test1="clr-namespace:test1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<test1:UserControl1 x:Name="test11" MyString="111"></test1:UserControl1>
<TextBox Height="23" HorizontalAlignment="Left" Margin="12,50,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding ElementName=test11, Path=MyString,UpdateSourceTrigger=PropertyChanged}"></TextBox>
</Grid>
</Window>
namespace test1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
框一会跟着框二进行变化。
3.链接
1.DependencyProperty
2.DependencyProperty
3.DependencyProperty
4.DependencyProperty
九.触发器
触发器通过Style.Triggers集合连接到样式中,每个样式都可以有任意多个触发器,并且每个触发器都是System.Window.TriggerBase的派生类实例。
- Trigger :监测依赖属性的变化,触发器生效
- MultiTrigger:通过多个条件的设置,达到满足条件,触发器生效
- DataTrigger:通过数据的变化,触发器生效
- MultiDataTrigger:多个数据条件的触发器
- EventTrigger:事件触发器,触发了某个事件时,触发器生效
<Window.Resources>
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="Content" Value="ZwW"/>
<Setter Property="Background" Value="BlanchedAlmond"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Blue"/>
<Setter Property="Content" Value="Button"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="BlanchedAlmond"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonStyle}">
<Setter Property="Content" Value="HHw"/>
<Setter Property="Background" Value="Azure"/>
</Style>
<Style x:Key="TextBoxTest" TargetType="{x:Type TextBox}">
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsFocused" Value="True"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="DarkCyan"/>
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style x:Key="DataTest" TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode= Self}, Path=Text}" Value="@">
<Setter Property="Background" Value="Honeydew"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>