重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含12115字,纯文字阅读大概需要18分钟。
内容图文
原文:重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试
作者:webabcd
介绍
重新想象 Windows 8 Store Apps
之 控件基础
- DependencyProperty - 依赖属性
- AttachedProperty - 附加属性
- 控件的继承关系
- 路由事件和命中测试
示例
1、开发一个具有 DependencyProperty 和 AttachedProperty
的自定义控件
MyControls/themes/generic.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyControls"><!-- 自定义控件的样式在本文件(themes/generic.xaml)中定义 整合外部 ResourceDictionary --><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="ms-appx:///MyControls/themes/MyControl.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary>
MyControls/themes/MyControl.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:MyControl"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="local:MyControl"><Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"><StackPanel><!--绑定自定义依赖属性--><TextBlock Text="{TemplateBinding Title}" Foreground="White" FontSize="26.667"/><!--绑定自定义附加属性--><TextBlock Text="{TemplateBinding local:MyAttachedProperty.SubTitle}" Foreground="White" FontSize="14.667"/></StackPanel></Border></ControlTemplate></Setter.Value></Setter></Style></ResourceDictionary>
MyControls/MyControl.cs
/* * 开发一个自定义控件,用于演示依赖属性(Dependency Property)和附加属性(Attached Property) * * 依赖属性:可以用于样式, 模板, 绑定, 动画 * 附加属性:全局可用的依赖属性 */using Windows.UI.Xaml.Controls; using Windows.UI.Xaml; namespace MyControls { ///<summary>/// 用于依赖属性的演示 ///</summary>publicclass MyControl : Control { public MyControl() { // 指定默认样式为 typeof(MyControl),即对应:<Style xmlns:local="using:MyControls" TargetType="local:MyControl" />this.DefaultStyleKey = typeof(MyControl); } // 通过 DependencyObject.GetValue() 和 DependencyObject.SetValue() 访问依赖属性,这里由 Title 属性封装一下,以方便对依赖属性的访问publicstring Title { get { return (string)GetValue(TitleProperty); } set { SetValue(TitleProperty, value); } } // 注册一个依赖属性publicstaticreadonly DependencyProperty TitleProperty = DependencyProperty.Register( "Title", // 依赖属性的名称typeof(string), // 依赖属性的数据类型typeof(MyControl), // 依赖属性所属的类new PropertyMetadata("", PropertyMetadataCallback)); // 指定依赖属性的默认值,以及值发生改变时所调用的方法privatestaticvoid PropertyMetadataCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args) { object newValue = args.NewValue; // 发生改变之后的值object oldValue = args.OldValue; // 发生改变之前的值 } } ///<summary>/// 用于附加属性的演示 ///</summary>publicclass MyAttachedProperty { // 获取附加属性publicstaticstring GetSubTitle(DependencyObject obj) { return (string)obj.GetValue(SubTitleProperty); } // 设置附加属性publicstaticvoid SetSubTitle(DependencyObject obj, string value) { obj.SetValue(SubTitleProperty, value); } // 注册一个附加属性publicstaticreadonly DependencyProperty SubTitleProperty = DependencyProperty.RegisterAttached( "SubTitle", // 附加属性的名称typeof(string), // 附加属性的数据类型typeof(MyAttachedProperty), // 附加属性所属的类new PropertyMetadata("", PropertyMetadataCallback)); // 指定附加属性的默认值,以及值发生改变时所调用的方法privatestaticvoid PropertyMetadataCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args) { object newValue = args.NewValue; // 发生改变之后的值object oldValue = args.OldValue; // 发生改变之前的值 } } }
2、演示依赖属性的使用
Controls/Basic/DependencyPropertyDemo.xaml
<Page x:Class="XamlDemo.Controls.Basic.DependencyPropertyDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Controls.Basic" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:myControls="using:MyControls" mc:Ignorable="d"><Grid Background="Transparent"><StackPanel Margin="120 0 0 0"><!-- 演示如何开发和使用自定义依赖属性(本例所用到的自定义控件请参看:MyControls/MyControl.cs) --><myControls:MyControl Background="Blue" BorderBrush="Yellow" BorderThickness="1" Width="100" HorizontalAlignment="Left" Title="{Binding Value, ElementName=slider}"/><Slider Name="slider" Width="100" Minimum="0" Maximum="200" IsThumbToolTipEnabled="False" HorizontalAlignment="Left"/></StackPanel></Grid></Page>
3、演示附加属性的使用
Controls/Basic/AttachedPropertyDemo.xaml
<Page x:Class="XamlDemo.Controls.Basic.AttachedPropertyDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Controls.Basic" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:myControls="using:MyControls" mc:Ignorable="d"><Grid Background="Transparent"><StackPanel Margin="120 0 0 0"><!-- 演示如何开发和使用自定义附加属性(本例所用到的自定义控件请参看:MyControls/MyControl.cs) --><myControls:MyControl Background="Blue" BorderBrush="Yellow" BorderThickness="1" Width="100" HorizontalAlignment="Left" Title="{Binding Value, ElementName=slider}" myControls:MyAttachedProperty.SubTitle="{Binding Value, ElementName=slider}"/><Slider Name="slider" Width="100" Minimum="0" Maximum="200" IsThumbToolTipEnabled="False" HorizontalAlignment="Left"/></StackPanel></Grid></Page>
4、控件的继承关系的概述
Controls/Basic/Inherit.xaml
<Page x:Class="XamlDemo.Controls.Basic.Inherit" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Controls.Basic" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"><Grid Background="Transparent"><StackPanel Margin="120 0 0 0"><TextBlock Name="lblMsg" FontSize="14.667" LineHeight="25"><Run>继承关系: FrameworkElement -> UIElement -> DependencyObject</Run><LineBreak /><Run>DependencyObject - 提供对依赖属性的访问,以及获取此对象关联的 CoreDispatcher</Run><LineBreak /><Run>UIElement - 可视元素,键盘和鼠标输入等</Run><LineBreak /><Run>FrameworkElement - 框架元素,数据绑定,一些公共 API 等。例:Control, TextBlock, WebView 等继承自 FrameworkElement</Run><LineBreak /><Run>ContentControl - 其内包含有一个内容,继承自 Control。例:ScrollViewer, AppBar 等继承自 ContentControl</Run><LineBreak /><Run>ButtonBase - 按钮的基本功能,继承自 ContentControl。例:Button, RepeatButton 等继承自 ButtonBase</Run><LineBreak /><Run>ToggleButton - 可切换状态的按钮,继承自 ButtonBase。例:RadioButton, CheckBox 等继承自 ToggleButton</Run><LineBreak /><Run>RangeBase - 值在某一范围内,继承自 ButtonBase。例:ProgressBar, Slider, ScrollBar 等继承自 RangeBase</Run><LineBreak /><Run>ItemsControl - 用于呈现集合,继承自 Control</Run><LineBreak /><Run>Selector - 可选择集合中的某一项,继承自 ItemsControl。例:ComboBox, ListBox, FlipView, ListViewBase 等继承自 Selector</Run><LineBreak /><Run>ListViewBase - 继承自 ListViewBase 的控件有 GridView 和 ListView</Run><LineBreak /><Run>Panel - 一个容器,继承自 FrameworkElement。例:Grid, StackPanel, Canvas 等继承自 Panel</Run><LineBreak /><Run>如 ScrollBar, Thumb, RangeBase, ButtonBase, Selector, Popup 等这类基元控件在 Windows.UI.Xaml.Controls.Primitives 命名空间下</Run></TextBlock></StackPanel></Grid></Page>
5、路由事件和命中测试
Controls/Basic/RoutedEventDemo.xaml
<Page x:Class="XamlDemo.Controls.Basic.RoutedEventDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Controls.Basic" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"><Grid Background="Transparent"><StackPanel Margin="120 0 0 0"><Grid HorizontalAlignment="Left" VerticalAlignment="Top"><!-- 演示事件冒泡:儿子传递事件给爸爸,爸爸传递事件给爷爷,这就是事件冒泡 --><Border Name="borderRed" Background="Red" Width="300" Height="300"><Border Name="borderGreen" Background="Green" Width="250" Height="250" Tapped="borderGreen_Tapped_1"><Border Name="borderBlue" Background="Blue" Width="200" Height="200" Tapped="borderBlue_Tapped_1"><Border Name="borderOrange" Background="Orange" Width="150" Height="150" Tapped="borderOrange_Tapped_1"><!--命中测试不可见,也就是说 borderPurple 和 borderYellow 均命中测试不可见--><Border Name="borderPurple" Background="Purple" Width="100" Height="100" Tapped="borderPurple_Tapped_1" IsHitTestVisible="False"><Border Name="borderYellow" Background="Yellow" Width="50" Height="50" Tapped="borderYellow_Tapped_1"/></Border></Border></Border></Border></Border><!-- 像这样排列元素,是没有事件冒泡的,而只是前面的元素响应事件,后面的元素不会响应事件,也就是说同辈间没有事件冒泡的概念 IsHitTestVisible - 是否对命中测试可见 <Rectangle Name="rectangle1" Width="800" Height="400" Fill="Red" /> <Rectangle Name="rectangle2" Width="700" Height="350" Fill="Green" /> <Rectangle Name="rectangle3" Width="600" Height="300" Fill="Blue" /> <Rectangle Name="rectangle4" Width="500" Height="250" Fill="Orange" /> <Rectangle Name="rectangle5" Width="400" Height="200" Fill="Purple" /> --></Grid><TextBlock Name="lblMsg" FontSize="14.667" Margin="0 10 0 0"/></StackPanel></Grid></Page>
Controls/Basic/RoutedEventDemo.xaml.cs
/* * 演示路由事件的冒泡和命中测试的可见性 * * TappedRoutedEventArgs * OriginalSource - 引发此路由事件的对象 * Handled - 是否将路由事件标记为已处理 * true - 不再冒泡 * false - 继续冒泡 * * UIElement * IsHitTestVisible - 是否对命中测试可见 */using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Input; namespace XamlDemo.Controls.Basic { publicsealedpartialclass RoutedEventDemo : Page { public RoutedEventDemo() { this.InitializeComponent(); // AddHandler() - 注册一个路由事件,注意最后一个参数:true 代表即使子辈 TappedRoutedEventArgs.Handled = true 也不会影响此元素事件的触发 // RemoveHandler() - 移除指定的路由事件 borderRed.AddHandler(UIElement.TappedEvent, new TappedEventHandler(borderRed_Tapped_1), true); } privatevoid borderRed_Tapped_1(object sender, TappedRoutedEventArgs e) { lblMsg.Text += "borderRed tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name; lblMsg.Text += Environment.NewLine; } privatevoid borderGreen_Tapped_1(object sender, TappedRoutedEventArgs e) { lblMsg.Text += "borderGreen tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name; lblMsg.Text += Environment.NewLine; } privatevoid borderBlue_Tapped_1(object sender, TappedRoutedEventArgs e) { lblMsg.Text += "borderBlue tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name; lblMsg.Text += Environment.NewLine; // 不会再冒泡,也就是说 borderGreen 无法响应 Tapped 事件,但是 borderRed 注册 Tapped 事件时 handledEventsToo = true,所以 borderRed 会响应 Tapped 事件 e.Handled = true; } privatevoid borderOrange_Tapped_1(object sender, TappedRoutedEventArgs e) { lblMsg.Text += "borderOrange tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name; lblMsg.Text += Environment.NewLine; } privatevoid borderPurple_Tapped_1(object sender, TappedRoutedEventArgs e) { // 不会响应此事件,因为 borderPurple 的 IsHitTestVisible = false lblMsg.Text += "borderPurple tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name; lblMsg.Text += Environment.NewLine; } privatevoid borderYellow_Tapped_1(object sender, TappedRoutedEventArgs e) { // 不会响应此事件,因为 borderYellow 的爸爸 borderPurple 的 IsHitTestVisible = false lblMsg.Text += "borderYellow tapped, originalSource: " + (e.OriginalSource as FrameworkElement).Name; lblMsg.Text += Environment.NewLine; } } }
OK
[源码下载]
原文:http://www.cnblogs.com/lonelyxmas/p/3588060.html
内容总结
以上是互联网集市为您收集整理的重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试全部内容,希望文章能够帮你解决重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。