背水一戰 Windows 10 (78) - 自定義控制項: 基礎知識, 依賴屬性, 附加屬性

来源:http://www.cnblogs.com/webabcd/archive/2017/12/14/8036180.html
-Advertisement-
Play Games

背水一戰 Windows 10 之 控制項(自定義控制項): 自定義控制項的基礎知識,依賴屬性和附加屬性 ...


[源碼下載]


背水一戰 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
[源碼下載]


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言: 在本系列第一篇《 "一步一步創建ASP.NET MVC5程式\[Repository+Autofac+Automapper+SqlSugar\" ][1]》中,我為大家介紹了搭建空白解決方案以及在此解決方案中創建目錄和對應的項目。本篇將和大家一起學習在項目中使用Nuget引入.NET對應的M ...
  • Excel表格中的迷你圖表能夠直觀地向我們展示出數據的變化趨勢。本文將介紹C#如何實現為表格數據生成迷你圖表,以及修改和刪除迷你圖表的方法。下麵將詳細講述。 所用組件工具:Spire.XLS for .NET 原Excel圖表: 一、添加迷你圖表(折線圖、柱形圖、盈虧圖) 1.添加命名空間 2.主要 ...
  • 1.引言 2.解決方案各部分介紹圖 3.添加數據模型 4.添加資料庫上下文 5.修改配置文件 6.使用依賴關係註入容器註冊資料庫上下文 7.添加基架工具並執行初始遷移 1.引言 NetCore出來有一段時間了,跨平臺、開源、高性能 讓每個從事.net的開發者都興奮了一把,對此我也有濃厚的興趣。 2. ...
  • 這篇是對象與集合操練,物件的創建,集合的一些基本功能,如添加,編輯,刪除等功能。 對象,即是網店的商品物件,Insus.NET只為其添加2個屬性,物件的ID的Key和名稱ItemName以及2個構造函數,最後一個方法是重寫ToString()方法。 class Item { private int ...
  • 每個版本的 .NET framework 都包含公共語言運行時 (CLR)、基類庫和其他托管庫。 本主題按版本介紹了 .NET Framework 的關鍵功能,提供了有關基礎 CLR 版本和相關開發環境的信息,並標識了 Windows 操作系統所安裝的版本。 備註 若要瞭解如何下載和安裝 .NET ...
  • 今天做了一個統計站點的網頁,想要發佈一下,中間碰到不少問題,現在和大家分享一下! 這是我想要最終的網頁結果: 1.發佈站點到桌面(任意路徑) 2.安裝IIS 3.安裝好後,打開IIS,新建站點web,結果瀏覽時,提示瀏覽文件的許可權不夠。於是,新建用戶Everyone,修改該web站點的許可權。 給Ev ...
  • .Net Core 將之前Web.Config中的配置遷移到了appsettings.json文件中,並使用ConfigurationBuilder來讀取這個配置文件。並可設置在配置文件變化以後,自動重新載入,這樣可不用重啟你的程式。 ...
  • 一、MVC簡介 MVC:Model-View-Controller(模型-視圖-控制器),MVC是一種軟體開發架構模式。 1、模型(Model) 模型對象是實現應用程式數據域邏輯的應用程式部件。 通常,模型對象會檢索模型狀態並將其存儲在資料庫中。 例如,Product 對象可能會從資料庫中檢索信息, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...