[源码下载]

背水一战 Windows 10 (76) - 控件(控件基类): Control - 基础知识, 焦点相关, 运行时获取 ControlTemplate 和 DataTemplate 中的元素

作者:webabcd

介绍
背水一战 Windows 10 之 控件(控件基类 - Control)

  • 基础知识
  • 焦点相关
  • 运行时获取 ControlTemplate 和 DataTemplate 中的元素

示例
1、演示 Control 的基础知识
Controls/BaseControl/ControlDemo/Demo1.xaml

<Page
x:Class="Windows10.Controls.BaseControl.ControlDemo.Demo1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Controls.BaseControl.ControlDemo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Orange"> <TextBox Name="textBox" Text="i am webabcd" TextWrapping="Wrap" AcceptsReturn="True" Margin="100" /> </Grid>
</Page>

Controls/BaseControl/ControlDemo/Demo1.xaml.cs

/*
* Control - Control(继承自 UIElement, 请参见 /Controls/BaseControl/FrameworkElementDemo/)
* Background - 背景 Brush
* Foreground - 前景 Brush
* BorderBrush - 边框 Brush
* BorderThickness - 边框 Thickness
* Padding - Padding
* FontSize - 字号大小(单位:像素)
* FontFamily - 首选字体,多个用“,”分隔,找不到第 1 个就用第 2 个,找不到第 2 个就用第 3 个,以此类推
* FontStretch - 字体的拉伸值(FontStretch 枚举),默认值是 Normal(大部分字体都不支持这个属性)
* FontStyle - 字体样式(FontStyle 枚举)
* Normal - 默认值
* Italic - 使用字体自带的斜体
* Oblique - 通过程序让正常字体倾斜(对于自身不带斜体的字体可以使用此值让字体倾斜)
* FontWeight - 字体粗细(FontWeights 实体类),默认值是 Normal
* CharacterSpacing - 用于设置字符间距
* 具体字符间隔像素计算公式如下:字体大小 * CharacterSpacing值 / 1000 = 字符间距像素值
* IsTextScaleFactorEnabled - 是否启用文本自动放大功能(默认值是 true)
* 在“设置”->“轻松使用”中可以调整文本缩放大小,IsTextScaleFactorEnabled 就是用于决定 TextBlock 显示的文本是否跟着这个设置走
* HorizontalContentAlignment - 内容的水平对齐方式
* VerticalContentAlignment - 内容的垂直对齐方式
* IsEnabled - 是否可用
* IsEnabledChanged - IsEnabled 属性的值发生变化时触发的事件
* Template - 控件模板,参见 /Controls/UI/ControlTemplate.xaml
*
*
* 本例用于演示 Control 的基础知识
*/ using System;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Text; namespace Windows10.Controls.BaseControl.ControlDemo
{
public sealed partial class Demo1 : Page
{
public Demo1()
{
this.InitializeComponent(); this.Loaded += Demo1_Loaded;
} private void Demo1_Loaded(object sender, RoutedEventArgs e)
{
ImageBrush imageBrush = new ImageBrush();
imageBrush.ImageSource = new BitmapImage(new Uri("ms-appx:///Assets/hololens.jpg", UriKind.Absolute));
imageBrush.Stretch = Stretch.Fill; textBox.Background = imageBrush; // 关于各种类型的 Brush 请参见 /Drawing/Brush.xaml
textBox.Foreground = new SolidColorBrush(Colors.DarkGreen);
textBox.BorderBrush = new SolidColorBrush(Colors.Red);
textBox.BorderThickness = new Thickness(, , , ); // 边框的占用空间是完全是在 Control 内部的
textBox.Padding = new Thickness(); textBox.FontSize = ;
textBox.FontFamily = new FontFamily("微软雅黑,宋体");
textBox.FontStretch = FontStretch.Normal;
textBox.FontStyle = FontStyle.Normal;
textBox.FontWeight = FontWeights.Normal;
textBox.CharacterSpacing = ;
textBox.IsTextScaleFactorEnabled = true; // 对于 TextBox 来说 HorizontalContentAlignment 和 VerticalContentAlignment 都是无效的
// 但是对于 Button 来说则可以通过 HorizontalContentAlignment 和 VerticalContentAlignment 来指定按钮上文字的对齐方式
textBox.HorizontalContentAlignment = HorizontalAlignment.Center;// 无效,如果需要设置文字内容的水平对齐方式的话请使用 textBox.TextAlignment
textBox.VerticalContentAlignment = VerticalAlignment.Center; // 无效 textBox.IsEnabledChanged += TextBox_IsEnabledChanged;
textBox.IsEnabled = false; // 注:如果要修 IsEnabled = false 的样式请查看名为 Disabled 的 VisualState
textBox.IsEnabled = true;
} private void TextBox_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
textBox.Text += Environment.NewLine;
textBox.Text += $"textBox.IsEnabled, OldValue:{e.OldValue}, NewValue:{e.NewValue}";
}
}
}

2、演示 Control 的焦点相关的知识点
Controls/BaseControl/ControlDemo/Demo2.xaml

<Page
x:Class="Windows10.Controls.BaseControl.ControlDemo.Demo2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Controls.BaseControl.ControlDemo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Orange">
<StackPanel Name="stackPanel" Background="Blue" Margin="100"> <!--
用于演示 TabIndex 和 IsTabStop
-->
<TextBox Name="textBox1" TabIndex="5" Margin="5" />
<TextBox Name="textBox2" TabIndex="3" Margin="5" />
<TextBox Name="textBox3" IsTabStop="False" TabIndex="4" Margin="5" />
<TextBox Name="textBox4" TabIndex="1" Margin="5" />
<TextBox Name="textBox5" TabIndex="2" Margin="5" /> <ComboBox Name="cmbTabNavigation" PlaceholderText="HorizontalAlignment" IsTabStop="False" SelectionChanged="cmbTabNavigation_SelectionChanged" Margin="5">
<ComboBoxItem IsSelected="True">Local</ComboBoxItem>
<ComboBoxItem>Cycle</ComboBoxItem>
<ComboBoxItem>Once</ComboBoxItem>
</ComboBox>
<!--
用于演示 TabNavigation
1、Local - 当 focus 至 itemsControl 时,会逐一 focus 其内部的所有 Control 元素,然后退出 focus
2、Cycle - 当 focus 至 itemsControl 时,会逐一 focus 其内部的所有 Control 元素,然后再继续无限循环 focus 其内部的所有 Control 元素
3、Once - 当 focus 至 itemsControl 时,只会 focus 其内部的第一个 Control 元素,然后退出 focus
-->
<ItemsControl Name="itemsControl" Margin="5" HorizontalAlignment="Left">
<ItemsControl.Items>
<TextBox />
<TextBox />
<TextBox />
</ItemsControl.Items>
</ItemsControl> <!--
用于演示 UseSystemFocusVisuals
1、UseSystemFocusVisuals="False" 获取焦点后,不会有任何效果,如果需要自定义获取焦点后的效果的话请在控件模板中设置
2、UseSystemFocusVisuals="True" 获取焦点后,由系统绘制效果(我这里测试的效果是,有一个虚线的边框显示)
-->
<Button Content="i am button 1" UseSystemFocusVisuals="False" Margin="5" />
<Button Content="i am button 2" UseSystemFocusVisuals="True" Margin="5" />
<Button Content="i am button 3" UseSystemFocusVisuals="False" Margin="5">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Target="border.BorderThickness" Value="5" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unfocused" />
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="border" BorderBrush="Red" BorderThickness="0">
<ContentPresenter x:Name="ContentPresenter"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"/>
</Border>
</Grid>
</ControlTemplate>
</Button.Template>
</Button> <!--
IsTemplateFocusTarget - 是否是控件内用于获取焦点的元素(附加属性)
-->
<Button Content="i am button 4" Margin="5">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
<Border x:Name="border" BorderBrush="Red" BorderThickness="0">
<StackPanel>
<ContentPresenter x:Name="ContentPresenter"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"/>
<!--
Control.IsTemplateFocusTarget="True" - 代表此 Button 控件用于获取焦点的元素是此 TextBlock
-->
<TextBlock Control.IsTemplateFocusTarget="True" Text="IsTemplateFocusTarget" />
</StackPanel>
</Border>
</Grid>
</ControlTemplate>
</Button.Template>
</Button> </StackPanel>
</Grid>
</Page>

Controls/BaseControl/ControlDemo/Demo2.xaml.cs

/*
* Control - Control(继承自 UIElement, 请参见 /Controls/BaseControl/FrameworkElementDemo/)
* FocusState - 当前的焦点状态(FocusState 枚举)
* Unfocused - 无焦点
* Pointer - 通过指针获取的焦点
* Keyboard - 通过键盘获取的焦点
* Programmatic - 通过 api 获取的焦点
* bool Focus(FocusState value) - 设置焦点状态
* TabIndex - Tab 键导航顺序(按 tab 键正序导航;按 shift + tab 键倒序导航),默认值为 int.MaxValue
* IsTabStop - 是否包含在 Tab 导航中(即是否可获取到焦点)
* TabNavigation - Tab 键导航至 Control 内部时的效果
* Local - 当 focus 至 Control 时,会逐一 focus 此 Control 内部的所有 Control 元素,然后退出 focus
* Cycle - 当 focus 至 Control 时,会逐一 focus 此 Control 内部的所有 Control 元素,然后再继续无限循环 focus 此 Control 内部的所有 Control 元素
* Once - 当 focus 至 Control 时,只会 focus 此 Control 内部的第一个 Control 元素,然后退出 focus
* UseSystemFocusVisuals - 是否使用系统的焦点效果
* false - 在控件模板中设置焦点效果
* true - 使用系统的焦点效果(我这里测试的效果是,获取焦点后会显示一个虚线边框)
* IsTemplateFocusTarget - 是否是控件内用于获取焦点的元素(附加属性)
* GotFocus - 获取焦点时触发的事件(来自 UIElement)
* LostFocus - 丢失焦点时触发的事件(来自 UIElement)
*
*
* 本例用于演示 Control 的焦点相关的知识点
*/ using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input; namespace Windows10.Controls.BaseControl.ControlDemo
{
public sealed partial class Demo2 : Page
{
public Demo2()
{
this.InitializeComponent(); this.Loaded += Demo2_Loaded;
} private void Demo2_Loaded(object sender, RoutedEventArgs e)
{
textBox1.GotFocus += TextBox1_GotFocus;
textBox2.GotFocus += TextBox2_GotFocus;
textBox3.GotFocus += TextBox3_GotFocus;
textBox4.GotFocus += TextBox4_GotFocus;
textBox5.GotFocus += TextBox5_GotFocus;
} private void TextBox1_GotFocus(object sender, RoutedEventArgs e)
{
textBox1.Text += textBox1.FocusState;
} private void TextBox2_GotFocus(object sender, RoutedEventArgs e)
{
textBox2.Text += textBox2.FocusState;
} private void TextBox3_GotFocus(object sender, RoutedEventArgs e)
{
textBox3.Text += textBox3.FocusState;
} private void TextBox4_GotFocus(object sender, RoutedEventArgs e)
{
textBox4.Text += textBox4.FocusState;
} // 这里当 textBox5 获取到焦点时,立刻指定 textBox2 获取焦点,则会达到禁止 textBox5 获取焦点的同时手动指定下一个焦点对象
// 如果只是禁止获取焦点的话可以设置 IsTabStop 为 false
private void TextBox5_GotFocus(object sender, RoutedEventArgs e)
{
textBox5.Text += textBox5.FocusState; // 设置为 FocusState.Unfocused 时会抛异常
bool success = textBox2.Focus(FocusState.Programmatic);
} private void cmbTabNavigation_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (itemsControl != null)
{
itemsControl.TabNavigation = (KeyboardNavigationMode)Enum.Parse(typeof(KeyboardNavigationMode), (e.AddedItems[] as ComboBoxItem).Content.ToString());
}
}
}
}

3、演示如何在运行时获取 ControlTemplate 和 DataTemplate 中的元素
Controls/BaseControl/ControlDemo/Demo3.xaml

<Page
x:Class="Windows10.Controls.BaseControl.ControlDemo.Demo3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Controls.BaseControl.ControlDemo"
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>
<!--
ControlTemplate - 控件模板(是 xaml 语言使用的一种方案,其无法在 c# 中定义)
-->
<ControlTemplate x:Key="MyControlTemplate" TargetType="ContentControl">
<Grid x:Name="grid">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate> <!--
DataTemplate - 数据模板(是 xaml 语言使用的一种方案,其无法在 c# 中定义)
-->
<DataTemplate x:DataType="common:Employee" x:Key="MyDataTemplate">
<TextBlock x:Name="textBlock" Text="{x:Bind Name}" />
</DataTemplate>
</Page.Resources> <Grid Background="Transparent">
<StackPanel Margin="10 0 10 10"> <local:MyContentControl x:Name="myContentControl" DataContext="{x:Bind CurrentEmployee}"
Template="{StaticResource MyControlTemplate}"
ContentTemplate="{StaticResource MyDataTemplate}" /> </StackPanel>
</Grid>
</Page>

Controls/BaseControl/ControlDemo/Demo3.xaml.cs

/*
* Control - Control(继承自 UIElement, 请参见 /Controls/BaseControl/FrameworkElementDemo/)
* GetTemplateChild() - 查找控件模板中的指定名字的元素
* OnApplyTemplate() - 应用控件模板时调用(来自 FrameworkElement)
*
* VisualTreeHelper - 可视化树的实用工具类
*
*
* 本例用于演示如何在运行时获取 ControlTemplate 和 DataTemplate 中的元素
*/ using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows10.Common; namespace Windows10.Controls.BaseControl.ControlDemo
{
public sealed partial class Demo3 : Page
{
public Employee CurrentEmployee { get; set; } = new Employee() { Name = "wanglei", Age = , IsMale = true }; public Demo3()
{
this.InitializeComponent(); myContentControl.Loaded += MyContentControl_Loaded;
} private void MyContentControl_Loaded(object sender, RoutedEventArgs e)
{
// 通过 VisualTreeHelper 获取可视化树结构(借此可以获取数据模板中的元素)
TextBlock textBlock = Helper.GetVisualChild<TextBlock>(myContentControl, "textBlock");
textBlock.FontSize = ;
}
} public class MyContentControl : ContentControl
{
// override OnApplyTemplate() - 应用控件模板时调用
protected override void OnApplyTemplate()
{
base.OnApplyTemplate(); // 在 OnApplyTemplate() 中通过 GetTemplateChild() 获取控件模板中的指定名字的元素
Grid grid = (Grid)GetTemplateChild("grid");
grid.Background = new SolidColorBrush(Colors.Orange);
}
}
}

OK
[源码下载]

背水一战 Windows 10 (76) - 控件(控件基类): Control - 基础知识, 焦点相关, 运行时获取 ControlTemplate 和 DataTemplate 中的元素的更多相关文章

  1. 背水一战 Windows 10 (101) - 应用间通信: 通过协议打开指定的 app 并传递数据以及获取返回数据, 将本 app 沙盒内的文件共享给其他 app 使用

    [源码下载] 背水一战 Windows 10 (101) - 应用间通信: 通过协议打开指定的 app 并传递数据以及获取返回数据, 将本 app 沙盒内的文件共享给其他 app 使用 作者:weba ...

  2. 背水一战 Windows 10 (12) - 绘图: Shape, Path

    [源码下载] 背水一战 Windows 10 (12) - 绘图: Shape, Path 作者:webabcd 介绍背水一战 Windows 10 之 绘图 Shape - 图形 Path - 路径 ...

  3. 背水一战 Windows 10 (16) - 动画: ThemeAnimation(主题动画)

    [源码下载] 背水一战 Windows 10 (16) - 动画: ThemeAnimation(主题动画) 作者:webabcd 介绍背水一战 Windows 10 之 动画 PopInThemeA ...

  4. 背水一战 Windows 10 (13) - 绘图: Stroke, Brush

    [源码下载] 背水一战 Windows 10 (13) - 绘图: Stroke, Brush 作者:webabcd 介绍背水一战 Windows 10 之 绘图 Stroke - 笔划 Brush ...

  5. 背水一战 Windows 10 (37) - 控件(弹出类): MessageDialog, ContentDialog

    [源码下载] 背水一战 Windows 10 (37) - 控件(弹出类): MessageDialog, ContentDialog 作者:webabcd 介绍背水一战 Windows 10 之 控 ...

  6. 背水一战 Windows 10 (36) - 控件(弹出类): ToolTip, Popup, PopupMenu

    [源码下载] 背水一战 Windows 10 (36) - 控件(弹出类): ToolTip, Popup, PopupMenu 作者:webabcd 介绍背水一战 Windows 10 之 控件(弹 ...

  7. 背水一战 Windows 10 (35) - 控件(弹出类): FlyoutBase, Flyout, MenuFlyout

    [源码下载] 背水一战 Windows 10 (35) - 控件(弹出类): FlyoutBase, Flyout, MenuFlyout 作者:webabcd 介绍背水一战 Windows 10 之 ...

  8. 背水一战 Windows 10 (34) - 控件(进度类): RangeBase, Slider, ProgressBar, ProgressRing

    [源码下载] 背水一战 Windows 10 (34) - 控件(进度类): RangeBase, Slider, ProgressBar, ProgressRing 作者:webabcd 介绍背水一 ...

  9. 背水一战 Windows 10 (33) - 控件(选择类): ListBox, RadioButton, CheckBox, ToggleSwitch

    [源码下载] 背水一战 Windows 10 (33) - 控件(选择类): ListBox, RadioButton, CheckBox, ToggleSwitch 作者:webabcd 介绍背水一 ...

随机推荐

  1. Creating adaptive web recommendation system based on user behavior(设计基于用户行为数据的适应性网络推荐系统)

    文章介绍了一个基于用户行为数据的推荐系统的实现步骤和方法.系统的核心是专家系统,它会根据一定的策略计算所有物品的相关度,并且将相关度最高的物品序列推送给用户.计算相关度的策略分为两部分,第一部分是针对 ...

  2. <thinkphp51>如何安装cpmposer和tp51

    进入网站之后点击 进入入门指南后点击 进入安装阶段: 1.直接next 2.选择自己的PHP文件路径 3.然后下一步下一步即可. 第二部分: 下载thinkphp51 点击安装包列表 搜索:think ...

  3. Aplication的意义和生命周期,与Context的关系,以及关于Aplication和Context相关问题的记录和解决办法

    Context详解地址链接: http://blog.csdn.net/qinjuning/article/details/7310620 Application是一个应用中有且仅有一个的全局共享变量 ...

  4. docker mysql Exit 1

    用laradock启动mysql时,state总是 Exit 1 ,docker-compose build后也没有效果 这时应该在-/.laradock/data(.env的DATA_PATH_HO ...

  5. JavaScript: RegExp check UserName

    Function : We can use regular expressions to check user input data formats. Homework: Check user inp ...

  6. java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一

    对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. java泛型详解 1. 概述 泛型在 ...

  7. centos 7 一键安装gitlab

    # cat /etc/redhat-release CentOS release 6.5 (Final) # strings /lib64/libc.so.6 |grep GLIBC_ 首先升级 如果 ...

  8. 从 ELK 到 EFK 的演进

    背景 作为中国最大的在线教育站点,目前沪江日志服务的用户包含网校,交易,金融,CCTalk 等多个部门的多个产品的日志搜索分析业务,每日产生的各类日志有好十几种,每天处理约10亿条(1TB)日志,热数 ...

  9. 【c++】内存检查工具Valgrind介绍,安装及使用以及内存泄漏的常见原因

    转自:https://www.cnblogs.com/LyndonYoung/articles/5320277.html Valgrind是运行在Linux上一套基于仿真技术的程序调试和分析工具,它包 ...

  10. CentOS No package nginx available.

    CentOS No package nginx available. yum install epel-release 如果不行 https://blog.csdn.net/u012965373/ar ...