背水一戰 Windows 10 (77) - 控件(控件基類): ContentControl, UserControl, Page


[源碼下載]


背水一戰 Windows 10 (77) - 控件(控件基類): ContentControl, UserControl, Page



作者:webabcd


介紹
背水一戰 Windows 10 之 控件(控件基類 - ContentControl, UserControl, Page)

  • ContentPresenter
  • ContentControl
  • UserControl
  • Page



示例
1、演示 ContentPresenter 的基礎知識
Controls/BaseControl/ContentControlDemo/ContentPresenterDemo.xaml

<Page
    x:Class="Windows10.Controls.BaseControl.ContentControlDemo.ContentPresenterDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.Controls.BaseControl.ContentControlDemo"
    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="10 0 10 10">

            <ContentControl Width="400" Margin="5" Content="我是 ContentControl" HorizontalAlignment="Left">
                <ContentControl.Template>
                    <ControlTemplate>
                        <Border BorderBrush="Red" BorderThickness="1">
                            <Grid Background="Yellow">
                                <!--
                                    ContentPresenter - 用來呈現 ContentControl 的 Content
                                        有一堆屬性,相關說明請參見文檔
                                -->
                                <ContentPresenter HorizontalAlignment="Right" Foreground="Black" FontSize="24" Padding="20" />
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </ContentControl.Template>
            </ContentControl>

        </StackPanel>
    </Grid>
</Page>

Controls/BaseControl/ContentControlDemo/ContentPresenterDemo.xaml.cs

/*
 * ContentPresenter - 用來呈現 ContentControl 的 Content(繼承自 FrameworkElement, 請參見 /Controls/BaseControl/FrameworkElementDemo/)
 * 
 * 
 * 注:關於如何創建自定義的 ContentPresenter 請參見 /Controls/CollectionControl/ItemsControlDemo/MyItemPresenterDemo.xaml
 */

using Windows.UI.Xaml.Controls;

namespace Windows10.Controls.BaseControl.ContentControlDemo
{
    public sealed partial class ContentPresenterDemo : Page
    {
        public ContentPresenterDemo()
        {
            this.InitializeComponent();
        }
    }
}


2、演示 ContentControl 的基礎知識
Controls/BaseControl/ContentControlDemo/ContentControlDemo.xaml

<Page
    x:Class="Windows10.Controls.BaseControl.ContentControlDemo.ContentControlDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.Controls.BaseControl.ContentControlDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    
    xmlns:common="using:Windows10.Common">

    <Page.Resources>
        <!--
            DataTemplate - 數據模板(其是 xaml 語言使用的一種方案,無法在 c# 中定義)
        -->
        <DataTemplate x:DataType="common:Employee" x:Key="DataTemplateMale">
            <Grid Background="Blue">
                <TextBlock Text="{x:Bind Name}" />
            </Grid>
        </DataTemplate>
        <DataTemplate x:DataType="common:Employee" x:Key="DataTemplateFemale">
            <Grid Background="Pink">
                <TextBlock Text="{x:Bind Name}" />
            </Grid>
        </DataTemplate>

        <!--
            自定義數據模板選擇器(參見 code-behind 中的代碼)
        -->
        <local:MyDataTemplateSelector x:Key="MyDataTemplateSelector" 
                                      DataTemplate1="{StaticResource DataTemplateMale}"
                                      DataTemplate2="{StaticResource DataTemplateFemale}" />
    </Page.Resources>

    
    <Grid Background="Transparent">
        <StackPanel Margin="10 0 10 10">

            <Button Name="button" Content="換個人" Click="button_Click" Margin="5" />

            <ContentControl Name="contentControl" Width="400" Margin="5" HorizontalAlignment="Left"
                            ContentTemplateSelector="{StaticResource MyDataTemplateSelector}">
                <ContentControl.ContentTransitions>
                    <TransitionCollection>
                        <ContentThemeTransition/>
                    </TransitionCollection>
                </ContentControl.ContentTransitions>
            </ContentControl>

        </StackPanel>
    </Grid>
</Page>

Controls/BaseControl/ContentControlDemo/ContentControlDemo.xaml.cs

/*
 * ContentControl - ContentControl(繼承自 Control, 請參見 /Controls/BaseControl/ControlDemo/)
 *     Content - 呈現的內容
 *     ContentTemplate - 數據模板(DataTemplate)
 *     ContentTemplateSelector - 數據模板選擇器(如果指定了 ContentTemplate 則此配置無效)
 *     ContentTemplateRoot - 用於獲取當前數據模板的根元素(寫自定義 ContentControl 時會用到)
 *     ContentTransitions - Content 發生變化時的過度效果
 */

using System;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows10.Common;

namespace Windows10.Controls.BaseControl.ContentControlDemo
{
    public sealed partial class ContentControlDemo : Page
    {
        private IList<Employee> Employees { get; set; } = TestData.GetEmployees(100);

        public ContentControlDemo()
        {
            this.InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            // 注:
            // 在 Content 發生變化時會觸發 ContentTemplateSelector 和 ContentTransitions(如果只是 DataContext 發生變化則不會有此效果)
            // 所以如果需要 ContentTemplateSelector 和 ContentTransitions 的話,則應該直接設置 ContentControl 的 Content 而不是 DataContext
            contentControl.Content =  Employees[new Random().Next(0, 100)];
        }
    }

    // 自定義 DataTemplateSelector(數據模板選擇器)
    // 可以實現在 runtime 時,根據 item 的不同選擇不同的數據模板
    public class MyDataTemplateSelector : DataTemplateSelector
    {
        // 數據模板 1(配置在 xaml 端)
        public DataTemplate DataTemplate1 { get; set; }

        // 數據模板 2(配置在 xaml 端)
        public DataTemplate DataTemplate2 { get; set; }

        // 根據 item 的數據的不同,指定的不同的模板
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            var employee = item as Employee;
            if (employee == null || employee.IsMale)
                return DataTemplate1; // 男員工用數據模板 1
            return DataTemplate2; // 女員工用數據模板 2

            // 如果想直接返回指定的資源也是可以的(但是不靈活),類似:return (DataTemplate)Application.Current.Resources["DataTemplateMale"];
        }
    }
}


3、演示 UserControl 的基礎知識
Controls/BaseControl/UserControlDemo/UserControlDemo.xaml

<Page
    x:Class="Windows10.Controls.BaseControl.UserControlDemo.UserControlDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.Controls.BaseControl.UserControlDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">

        <UserControl Margin="10 0 10 10" HorizontalAlignment="Left" VerticalAlignment="Top">
            <UserControl.Content>
                <Rectangle Width="300" Height="100" Fill="Orange" />
            </UserControl.Content>
        </UserControl>

        <!--
            UserControl 有一個 [ContentProperty(Name = "Content")] 聲明,所以在寫 xaml 的時候可以省略掉 UserControl.Content
        -->
        <UserControl Margin="10 130 10 10" HorizontalAlignment="Left" VerticalAlignment="Top">
            <Rectangle Width="300" Height="100" Fill="Orange" />
        </UserControl>

    </Grid>
</Page>

Controls/BaseControl/UserControlDemo/UserControlDemo.xaml.cs

/*
 * UserControl - UserControl(繼承自 Control, 請參見 /Controls/BaseControl/ControlDemo/)
 *     Content - 呈現的內容
 */

using Windows.UI.Xaml.Controls;

namespace Windows10.Controls.BaseControl.UserControlDemo
{
    public sealed partial class UserControlDemo : Page
    {
        public UserControlDemo()
        {
            this.InitializeComponent();
        }
    }
}


4、演示 Page 的基礎知識
Controls/BaseControl/PageDemo/PageDemo.xaml

<Page
    x:Class="Windows10.Controls.BaseControl.PageDemo.PageDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.Controls.BaseControl.PageDemo"
    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="10 0 10 10">

            <TextBlock Name="lblMsg" Margin="5" TextWrapping="Wrap" />

        </StackPanel>
    </Grid>
</Page>

Controls/BaseControl/PageDemo/PageDemo.xaml.cs

/*
 * Page - Page(繼承自 UserControl, 請參見 /Controls/BaseControl/UserControlDemo/)
 *     TopAppBar, BottomAppBar - 參見 /Controls/NavigationControl/AppBarDemo.xaml 和 /Controls/NavigationControl/CommandBarDemo.xaml
 *     NavigationCacheMode, OnNavigatedFrom(), OnNavigatingFrom(), OnNavigatingFrom() - 參見 /Controls/NavigationControl/FrameDemo.xaml
 *     Frame - 獲取當前 Page 的所屬 Frame
 */

using System;
using System.Diagnostics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace Windows10.Controls.BaseControl.PageDemo
{
    public sealed partial class PageDemo : Page
    {
        public PageDemo()
        {
            this.InitializeComponent();

            this.Loading += page_Loading;
            this.Loaded += page_Loaded;
            this.Unloaded += page_Unloaded;
        }


        // 在 OnNavigatedTo 之后,由外到內觸發 Loading 事件,由內到外觸發 Loaded 事件;在 OnNavigatedFrom 之后,由外到內觸發 Unloaded 事件(參見 /Controls/BaseControl/FrameworkElementDemo/Demo2.xaml.cs)
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            lblMsg.Text += "OnNavigatedTo";
            lblMsg.Text += Environment.NewLine;
        }
        protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
        {
            Debug.WriteLine("OnNavigatingFrom");
        }
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            Debug.WriteLine("OnNavigatedFrom");
        }


        // 在 OnNavigatedTo 之后,由外到內觸發 Loading 事件,由內到外觸發 Loaded 事件;在 OnNavigatedFrom 之后,由外到內觸發 Unloaded 事件(參見 /Controls/BaseControl/FrameworkElementDemo/Demo2.xaml.cs)
        private void page_Loading(FrameworkElement sender, object args)
        {
            lblMsg.Text += "page_Loading";
            lblMsg.Text += Environment.NewLine;
        }
        private void page_Loaded(object sender, RoutedEventArgs e)
        {
            lblMsg.Text += "page_Loaded";
            lblMsg.Text += Environment.NewLine;
        }
        private void page_Unloaded(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("page_Unloaded");
        }
    }
}



OK
[源碼下載]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM