背水一战 Windows 10 (78) - 自定义控件: 基础知识, 依赖属性, 附加属性
作者:webabcd
介绍
背水一战 Windows 10 之 控件(自定义控件)
- 自定义控件的基础知识,依赖属性和附加属性
示例
演示自定义控件的基础知识,依赖属性和附加属性
1、自定义控件的示例
/MyControls/themes/generic.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!--
在 themes/generic.xaml 中定义自定义控件的默认样式
-->
<ResourceDictionary.MergedDictionaries>
<!--
注意:
此处在指定 xaml 路径时,要以“项目名”为根路径(因为这个自定控件的项目是要被别的项目引用的)
这个是对的 ms-appx:///MyControls/themes/MyControl1.xaml
这个是错的 ms-appx:///themes/MyControl1.xaml(编译时不会报错,运行时会报错 Failed to assign to property 'Windows.UI.Xaml.ResourceDictionary.Source' because the type 'Windows.Foundation.String' cannot be assigned to the type 'Windows.Foundation.Uri')
-->
<ResourceDictionary Source="ms-appx:///MyControls/themes/MyControl1.xaml"/>
<ResourceDictionary Source="ms-appx:///MyControls/themes/MyControl3.xaml"/>
</ResourceDictionary.MergedDictionaries> </ResourceDictionary>
/MyControls/themes/MyControl1.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyControls"> <Style TargetType="local:MyControl1">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyControl1">
<!--
绑定基类中定义的依赖属性
-->
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel> <!--
绑定自定义依赖属性
-->
<TextBlock Text="{TemplateBinding Title}" Foreground="White" FontSize="24" /> <!--
绑定自定义附加属性
-->
<TextBlock Text="{TemplateBinding local:MyAttachedProperty.SubTitle}" Foreground="Orange" FontSize="24" /> </StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style> </ResourceDictionary>
/MyControls/MyAttachedProperty.cs
/*
* 定义一个附加属性(Attached Property)
*
* 依赖属性:可以用于样式, 模板, 绑定, 动画
* 附加属性:全局可用的依赖属性
*/ using Windows.UI.Xaml; namespace MyControls
{
/// <summary>
/// 定义一个附加属性(Attached Property)
/// </summary>
public sealed class MyAttachedProperty
{
// 获取附加属性
public static string GetSubTitle(DependencyObject obj)
{
return (string)obj.GetValue(SubTitleProperty);
} // 设置附加属性
public static void SetSubTitle(DependencyObject obj, string value)
{
obj.SetValue(SubTitleProperty, value);
} // 注册一个附加属性(winrc 中不支持 public 类型的 field,如果是 dll 项目则无此限制)
private static readonly DependencyProperty SubTitlePropertyField =
DependencyProperty.RegisterAttached(
"SubTitle", // 附加属性的名称
typeof(string), // 附加属性的数据类型
typeof(MyAttachedProperty), // 附加属性所属的类
new PropertyMetadata("", PropertyMetadataCallback)); // 指定附加属性的默认值,以及值发生改变时所调用的方法 // 用属性的方式封装一下 SubTitlePropertyField
public static DependencyProperty SubTitleProperty
{
get
{
return SubTitlePropertyField;
}
} private static void PropertyMetadataCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
object newValue = args.NewValue; // 发生改变之后的值
object oldValue = args.OldValue; // 发生改变之前的值
}
}
}
/MyControls/MyControl1.cs
/*
* 开发一个自定义控件,并定义一个依赖属性(Dependency Property)
*
* 依赖属性:可以用于样式, 模板, 绑定, 动画
* 附加属性:全局可用的依赖属性
*/ using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml; namespace MyControls
{
/// <summary>
/// 开发一个自定义控件,并定义一个依赖属性(Dependency Property)
/// </summary>
// 注意:
// 在 winrc 中用 c# 写的类必须是 sealed 的(否则编译时会报错 Exporting unsealed types is not supported.Please mark type 'MyControls.MyControl1' as sealed)
// 如果是 dll 项目则无此限制
public sealed class MyControl1 : Control
{
public MyControl1()
{
// 指定默认样式为 typeof(MyControl1),即使用 TargetType 为 MyControl1 的样式,即 <Style xmlns:local="using:MyControls" TargetType="local:MyControl1" />
// 如果不指 DefaultStyleKey 的话,则默认使用基类即 Control 的样式
this.DefaultStyleKey = typeof(MyControl1);
} // 通过 DependencyObject.GetValue() 和 DependencyObject.SetValue() 访问依赖属性,这里由 Title 属性封装一下,以方便对依赖属性的访问
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
} // 注册一个依赖属性
// 注意:
// 在 winrc 中不支持 public 类型的 field(在 dll 项目无此限制),所以这里改为 private 的,之后再用 public 属性的方式封装一下即可
// 如果使用了 public 类型的 field 的话,编译时会报错 Type 'MyControls.MyControl1' contains externally visible field 'Windows.UI.Xaml.DependencyProperty MyControls.MyControl1.TitlePropertyField'. Fields can be exposed only by structures
private static readonly DependencyProperty TitlePropertyField =
DependencyProperty.Register(
"Title", // 依赖属性的名称
typeof(string), // 依赖属性的数据类型
typeof(MyControl1), // 依赖属性所属的类
new PropertyMetadata("", PropertyMetadataCallback)); // 指定依赖属性的默认值,以及值发生改变时所调用的方法 // 用属性的方式封装一下 TitlePropertyField
public static DependencyProperty TitleProperty
{
get
{
return TitlePropertyField;
}
} private static void PropertyMetadataCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
object newValue = args.NewValue; // 发生改变之后的值
object oldValue = args.OldValue; // 发生改变之前的值
}
}
}
2、调用自定义控件的示例
Controls/CustomControl/Demo1.xaml
<Page
x:Class="Windows10.Controls.CustomControl.Demo1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Controls.CustomControl"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" xmlns:myControls="using:MyControls"> <Grid Background="Transparent">
<StackPanel Margin="10 0 10 10"> <!--
演示自定义控件的基础知识,依赖属性和附加属性
本例所用到的自定义控件请参看:MyControls/MyControl1.cs
--> <!--
依赖属性和附加属性可以用于绑定
-->
<myControls:MyControl1 x:Name="control1" Background="Blue" BorderBrush="Yellow" BorderThickness="1" Width="200" HorizontalAlignment="Left" Margin="5"
Title="{Binding Value, ElementName=slider}"
myControls:MyAttachedProperty.SubTitle="{Binding Value, ElementName=slider}">
</myControls:MyControl1>
<Slider Name="slider" Width="200" Minimum="0" Maximum="200" IsThumbToolTipEnabled="False" HorizontalAlignment="Left" Margin="5" Foreground="Orange" Background="White" Style="{StaticResource MySliderStyle}" /> <!--
依赖属性和附加属性可以用于 Storyboard 动画
但是无法通过 Storyboard 对自定义附加属性做动画,在文档中找到了这样一句话“However, an existing limitation of the Windows Runtime XAML implementation is that you cannot animate a custom attached property.”
-->
<myControls:MyControl1 x:Name="control2" Background="Blue" BorderBrush="Yellow" BorderThickness="1" Width="200" HorizontalAlignment="Left" Margin="5">
<myControls:MyControl1.Resources>
<BeginStoryboard x:Name="storyboard1">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="control2" Storyboard.TargetProperty="Title" Duration="0:0:10" RepeatBehavior="Forever">
<DiscreteObjectKeyFrame KeyTime="0:0:1" Value="w" />
<DiscreteObjectKeyFrame KeyTime="0:0:2" Value="we" />
<DiscreteObjectKeyFrame KeyTime="0:0:3" Value="web" />
<DiscreteObjectKeyFrame KeyTime="0:0:4" Value="weba" />
<DiscreteObjectKeyFrame KeyTime="0:0:5" Value="webab" />
<DiscreteObjectKeyFrame KeyTime="0:0:6" Value="webabc" />
<DiscreteObjectKeyFrame KeyTime="0:0:7" Value="webabcd" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</myControls:MyControl1.Resources>
</myControls:MyControl1> <!--
在 code-behind 中设置依赖属性和附加属性
-->
<myControls:MyControl1 x:Name="control3" Background="Blue" BorderBrush="Yellow" BorderThickness="1" Width="200" HorizontalAlignment="Left" Margin="5" /> </StackPanel>
</Grid>
</Page>
Controls/CustomControl/Demo1.xaml.cs
/*
* 本例用于演示自定义控件的基础知识,依赖属性和附加属性
*/ using MyControls;
using Windows.UI.Xaml.Controls; namespace Windows10.Controls.CustomControl
{
public sealed partial class Demo1 : Page
{
public Demo1()
{
this.InitializeComponent(); this.Loaded += Demo1_Loaded;
} private void Demo1_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
// 设置依赖属性
control3.Title = "我是依赖属性"; // 设置附加属性
control3.SetValue(MyAttachedProperty.SubTitleProperty, "我是附加属性");
}
}
}
OK
[源码下载]
背水一战 Windows 10 (78) - 自定义控件: 基础知识, 依赖属性, 附加属性的更多相关文章
- 背水一战 Windows 10 (79) - 自定义控件: Layout 系统, 控件模板, 事件处理
[源码下载] 背水一战 Windows 10 (79) - 自定义控件: Layout 系统, 控件模板, 事件处理 作者:webabcd 介绍背水一战 Windows 10 之 控件(自定义控件) ...
- 背水一战 Windows 10 (87) - 文件系统: 获取文件的属性, 修改文件的属性, 获取文件的缩略图
[源码下载] 背水一战 Windows 10 (87) - 文件系统: 获取文件的属性, 修改文件的属性, 获取文件的缩略图 作者:webabcd 介绍背水一战 Windows 10 之 文件系统 获 ...
- 背水一战 Windows 10 (76) - 控件(控件基类): Control - 基础知识, 焦点相关, 运行时获取 ControlTemplate 和 DataTemplate 中的元素
[源码下载] 背水一战 Windows 10 (76) - 控件(控件基类): Control - 基础知识, 焦点相关, 运行时获取 ControlTemplate 和 DataTemplate 中 ...
- 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, VerticalAlignment
[源码下载] 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, Vertical ...
- 背水一战 Windows 10 (63) - 控件(WebView): 基础知识, 加载 html, http, https, ms-appx-web:///, embedded resource, ms-appdata:///, ms-local-stream://
[源码下载] 背水一战 Windows 10 (63) - 控件(WebView): 基础知识, 加载 html, http, https, ms-appx-web:///, embedded res ...
- 背水一战 Windows 10 (50) - 控件(集合类): ItemsControl - 基础知识, 数据绑定, ItemsPresenter, GridViewItemPresenter, ListViewItemPresenter
[源码下载] 背水一战 Windows 10 (50) - 控件(集合类): ItemsControl - 基础知识, 数据绑定, ItemsPresenter, GridViewItemPresen ...
- 背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项
[源码下载] 背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合 ...
- 背水一战 Windows 10 (110) - 通知(Tile): secondary tile 模板之基础, secondary tile 模板之文本
[源码下载] 背水一战 Windows 10 (110) - 通知(Tile): secondary tile 模板之基础, secondary tile 模板之文本 作者:webabcd 介绍背水一 ...
- 背水一战 Windows 10 (108) - 通知(Tile): application tile 基础, secondary tile 基础
[源码下载] 背水一战 Windows 10 (108) - 通知(Tile): application tile 基础, secondary tile 基础 作者:webabcd 介绍背水一战 Wi ...
随机推荐
- Python 进行查询日志查询条件分析
任务:crm日志的查询条件 每次是哪几个字段查,有几种组合 ,统计每种组合查询的量 日志样例: -- ::] -- ::] 查询条件:query查询条件可以多个,用|and|分割. 步骤: 1.正则 ...
- This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.
This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.
- RAD Studio 10.3 来了
官方原版下载链接:HTTP FTP 官方更新说明:http://docwiki.embarcadero.com/RADStudio/Rio/en/What's_New [官方更新说明简译]1.Delp ...
- Python文件操作---合并文本文件内容
目前一个用的比较多的功能:将多个小文件的内容合并在一个统一的文件中,对原始文件重命名标记其已被处理过.之前使用其他脚本写的,尝试用python写了一下,顺便熟悉一下python的文件处理命令. 原始文 ...
- Delphi TXLSReadWriteII导出Excel
TXLSReadWriteII导出Excle (有点复杂,可以自己简化一下,直接从项目中抓取的) procedure TformSubReport.DataToExcel(_Item: Integer ...
- python学习Day2 python 、pycharm安装及环境变量配置
复习 进制转换:二进制&十六进制转换(从左往右1248机制,每四位二进制对应一位16进制) 二进制&十进制转换 2n-1幂次方相加 十进制到二进制转化 将十进制除以2,把余数记下 ...
- 简单的TSQL基础编程格式,存储过程,视图
这里简单整理一下数据库简单的编程,变量定义,赋值,分支语句和循环(这里以Sqlserver),以及存储过程格式 首先是变量定义,赋值,分支语句 --======TSQL数据库基础编程,定义变量,赋值, ...
- spark快速开发之scala基础之5高阶函数,偏函数,闭包
高阶函数 高阶函数就是将函数作为参数或者返回值的函数. object function { def main(args: Array[String]): Unit = { println(test(f ...
- mysql5.5升级到5.7
一.首先把mysql服务停止,复制mysql5.5中的data文件夹中的内容(你需要的数据库),放在mysql5.7的data文件夹中; 二.启动切换mysql5.7版本,(我这用的是phpwamp, ...
- CentOS 特殊变量($0、$1、$2、 $?、 $# 、$@、 $*)
名称 说明 $0 脚本名称 $1-9 脚本执行时的参数1到参数9 $? 脚本的返回值 $# 脚本执行时,输入的参数的个数 $@ 输入的参数的具体内容(将输入的参数作为一个多个对象,即是所有参数的一个列 ...