背水一戰 Windows 10 之 控制項(控制項基類 - ContentControl, UserControl, Page): ContentPresenter, 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
[源碼下載]