zoukankan      html  css  js  c++  java
  • 背水一战 Windows 10 (78)

    [源码下载]


    背水一战 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
    [源码下载]

  • 相关阅读:
    rabbitmq 学习6rabbitmq基础
    使用Sqlserver事务发布实现数据同步
    rabbitmq 学习2安装
    window server 2003 下安装squid
    rabbitmq 学习3初试1
    rabbitmq 学习5server管理
    RabbitMQ: high performance messaging solution
    AMQP和RabbitMQ入门
    rabbitmq 学习1AMQP介绍
    [解题报告]11689 Soda Surpler
  • 原文地址:https://www.cnblogs.com/webabcd/p/8036180.html
Copyright © 2011-2022 走看看