模仿ItemsControl 顾名思义,ItemsControl是展示一组数据的控件,它是UWP UI系统中最重要的控件之一,和展示单一数据的ContentControl构成了UWP UI的绝大部分,ComboBox...曾经有个说法:了解ContentControl和ItemsControl才能算是了解WPF的控件,这一点在UWP中也是一样的。 ?...以我的经验来说,通过继承ItemsControl来自定义模板化控件十分常见,了解ItemsControl对将来要自定义模板化控件十分有用。...注意: UWP中ItemsControl默认没有启用UI虚拟化,但它的派生类有。...控件中的集合属性一般遵循以下做法: 3.1 只读属性 public IList Sections { get; } 这是Hub的Section属性,模板化控件中的集合类型属性基本都定义成这样的
使用TemplatePart 上一篇文章构造了一个很基础的控件HeaderedContentControl,这次通过扩展这个类做些试验性质的功能来介绍模板化控件的进阶知识。...新建一个名为ContentView的控件,继承自HeaderedContentControl,它要实现的功能有两个: 控件的Header默认Opacity=0.7,当鼠标移动到控件上时,设置Header...Header}" ContentTemplate="{TemplateBinding HeaderTemplate}" /> 2.2 获取TemplatePart 模板化控件在加载...出于性能方面的考虑,很多UWP原生控件都会包含x:DeferLoadStrategy="Lazy"。 4....TemplatePartAttribute在UWP中的作用好像被弱化了,不止在UWP原生控件中见不到TemplatePartAttribute,甚至在Blend中“部件”窗口也消失了。
VisualState 指定控件处于特定状态时的外观。...控件的代码指定控件处于何种状态,控件的ControlTemplate中根节点包含VisualStateManager.VisualStateGroups附加属性,并在其中确定各个VisualState的外观...在同一个VisualStateGroup中的VisualState是互斥的,控件始终只能处于每组状态中的一种。例如,控件只能处于NoHeader状态,或者HasHeader状态。...模板化控件可以使用TemplateVisualStateAttribute协定声明它的VisualState,用于通知控件的使用者有这些VisualState可用。...VisualStateManager.GoToState不会使控件重复进入某个状态,譬如如果控件已处于PointerOverState,再次调用VisualStateManager.GoToState(
如果正在从头设计自定义控件并真的需要提供命令支持,可以参考这篇文章。支持Command的步骤比较简单,所以这篇文章比较简短。...要实现Command支持,控件中要执行如下步骤: 定义Command和CommandParameter属性。 监视Command的CanExecuteChanged事件。...CanExecuteChanged的事件处理函数及CommandParameter的PropertyChangedCallback中,根据Command.CanExecute(CommandParameter)的结果设置控件的
UWP的UI主要由布局容器和内容控件(ContentControl)组成。布局容器是指Grid、StackPanel等继承自Panel,可以拥有多个子元素的类。...在UWP中,Button、CheckBox、ScrollViewer、Frame、ToolTip等都继承自ContentControl,其它控件则不是在ContentTemplate中使用ContentControl...,就是被ContentControl使用,可以说ContentControl是UWP中最重要的控件。...注意:ContentTemplateSelector的缺点是需要创建多个模板,通常同一组数据的模板只有少部分的差别,可以在同一个模板中通过IValueConverter等方式显示不同的格式。...AddDeleteThemeTransition /> UWP
ContentControl是最简单的TemplatedControl,而且它在UWP出场频率很高。...这次的内容就是模仿ContentControl实现一个模板化控件MyContentControl,直接继承自Control。 1....在UWP中如无特殊需求,Content、Header、Title等内容属性最好都是Object类型,这样更方便扩展,例如可以在Header放一个Checkbox,这是很常见的做法。 2....UWP通过ControlTemplate定义控件的外观。...除了可属性值继承的属性,需要适当地将ControlTemplate中的元素属性绑定到所属控件的属性,例如Margin="{TemplateBinding Padding}",这样可以方便控件的使用者通过属性调整
这个示例中除了ListBox控件其它都自带Header,但是ListBox没有Header属性,只好用一个TextBlock模仿它的Header。...这样就带来一个问题:只有ListBox的Header高度和其它控件不一致。 既然现在讨论的是自定义控件,这里就用自定义控件的方式解决这个问题。...Header="ListBox"> 这样,只要在HeaderedContentControl的样式中模仿其它含Header属性的控件...WPF中本来就有这个控件,它是Expander、GroupBox、TabItem等诸多拥有Header属性的控件的基类,十分方便好用。...UWP中模仿这个控件很简单,而且很适合用来学习自定义控件的进阶知识。 2.
IsTabStop 要在UI上使用“Tab”键导航到某个控件,需要将这个控件的IsTabStop设置为True(默认值就是True)。如果设置成False,不止不能导航到,而且还不能获得焦点。...再重申一次,模板化控件的属性默认值要在DefaultStyle中设置,尽量不要在构造函数中设置。 5....处理焦点外观 5.1 FocusVisual FocusVisual指控件获得焦点时的视觉指示器,默认是一个围绕控件边界的矩形边框。通常只用Tab键导航并获得焦点FocusVisual才会显示。...; Unfocused: 没获得任何焦点的状态; PointerFocused: 点击控件并获得焦点的状态; Control自身已处理好在这三个状态中转换的逻辑,不需要额外写代码来转换状态。...幸好现在的主流是扁平化的简单的设计,在UWP中按钮的模板被大大简化: <ContentPresenter x:Name="ContentPresenter" BorderBrush="{TemplateBinding
我遇到一个问题,我在 xaml 用了我的自定义控件,但是我给他设置了一个值,但是什么时候我才可以获得这个值? 本文告诉大家,从构造函数、loaded、Initialized 的调用过程。...用最简单的方法创建一个自定义控件,然后在他里面写一个属性 public static readonly DependencyProperty AmameProperty = DependencyProperty.Register
原则 推荐以符合以下原则的方式编写模板化控件: 选择合适的父类:选择合适的父类可以节省大量的工作,从UWP自带的控件中选择父类是最安全的做法,通常的选择是Control、ContentControl、ItemsControl...小技巧 对于复杂的控件或控件库项目,以下技巧可能对你有帮助。 3.1 partial class 在编写模板化控件时,依赖属性最大的缺点会暴露无遗:它太复杂了。...3.2 合并资源字典 如果一个项目的模板化控件太多,Generic.xaml会异常的复杂,可以将各个控件的资源文件分开存放,再在Generic.xaml中合并它们。...结语 这个系列的主旨是讲解常见的模板化控件技术,希望了解这些技术后能更轻松地构造自己的控件,对理解开源控件库的代码也有一定的帮助。...职业生涯中看过很多程序员都不会写模板化控件(毕竟大部分场景使用UserControl或修改ControlTemplate就能解决),希望这个系列可以帮到想要学习模板化控件的开发者。
基本需求 之前的ContentView2添加了PointerOver等效果,和TextBox等本来就有Header的控件放在一起反而变得鹤立鸡群。...为了解决这个问题,这次把ContentView2的Header部分分离出来做成一个可复用的控件HeaderView,它继承自Control,并且拥有Header属性及AttachElement属性。...把它放到其他控件的ControlTemplate替换原本的HeaderContentPresenter,这样就能统一外观了。...Header="{TemplateBinding Header}" /> AttachedElement使用Mode=TemplatedParent的绑定,获取模板所属的控件...使用附加属性 如果要为所有含有Header属性的控件修改ControlTemplate,这将是一个很麻烦的工作。为了避免重复性工作,可以尝试用附加属性解决。
1.概述 UWP允许开发者通过两种方式创建自定义的控件:UserControl和TemplatedControl(模板化控件)。...这个主题主要讲述如何创建和理解模板化控件,目标是能理解模板化控件常见的知识点,并且可以创建扩展性良好的模板化控件。...1.2 模板化控件 可以使用ControlTemplate的控件即为模板化控件(TemplatedControl),在UWP中,所有派生自Control的控件(除了UserControl)都是模板化控件...可以不存在DefaultStyle,所以某些场合会把模板化控件称为“无外观控件”。 2. 创建第一个模板化控件 下面介绍如何使用VisualStudio在一个新项目中创建一个模板化控件。 ?...由于这个主题主要目的是介绍模板化控件,所以不会深入讨论Blend的操作。
不过在实际应用中这两种实现方式并不是互斥的,很多模板化控件都同时使用这两种方式, 使用VisualState有如下好处: 代码和UI分离。 可以更灵活地扩展控件。 可以使用Blend轻松实现动画。...前面的例子展示了使用VisualState在UI上的优势,这次用另一个控件DateTimeSelector来讨论使用TemplatePart在扩展性上的其它问题。...DateTimeSelector的代码很简单,控件也工作得很好,但如果某天需要将CalendarDatePicker 替换为DatePicker或某个第三方的日期选择控件,DateTimeSelector...使用TemplateBinding 通常在构建这类控件时应先考虑它的数据和行为,而不关心它的UI。...ControlTemplate中包含什么控件,它只关心自己的数据。
TemplatedControl 在UWP中自定义控件常常会遇到这个问题:使用UserControl还是TemplatedControl来自定义控件。...1.1 使用UserControl自定义控件 继承自UserControl。 由复数控件组合而成。 包含XAML及CodeBehind。 优点: 上手简单。...使用场景: 需要快速实现一个只有简单功能的控件,而且无需扩展性。 不需要可以改变UI。 不需要在不同项目中共享控件。...使用UserControl的控件: Page及DropShadowPanel都是UserControl。 1.2 使用CustomControl自定义控件 继承自Control或其派生类。...控件库中的控件通常都是CustomControl。 优点: 更加灵活,容易扩展。 UI和代码分离。 缺点: 较高的上手难度。 使用场景: 需要一个可以扩展功能的灵活的控件。 需要定制UI。
如何拖动一个TextBlock的文字到另一个TextBlock win10 uwp 如何让 Page 继承泛型类 win10 uwp 如何让一个集合按照需要的顺序进行排序 win10 UWP 序列化...uwp 绑定 OneWay 无法使用 win10 uwp 绑定密码 win10 uwp 绑定静态属性 win10 uwp 自定义控件初始化 win10 uwp 获取指定的文件 win10 uwp 获取按钮鼠标左键按下...win10 uwp 获取文件夹出错 win10 uwp 获得元素绝对坐标 win10 uwp 获得缩略图 win10 uwp 萤火虫效果 win10 uwp 让焦点在点击在页面空白处时回到textbox...type-使用构造 win10-uwp-使用md5算法 win10-uwp-保存用户选择文件夹 win10-uwp-入门 win10-uwp-兴趣线 win10-uwp-切换主题 win10-uwp-列表模板选择器...鼠标放开的值 win10-uwp-获得焦点改变 win10-uwp-访问解决方案文件 win10-uwp-车表盘-径向规 win10-uwp-随着数字变化颜色控件 win10-uwp-隐私声明 win10
所谓的最好,是因为WPF、Silverlight、UWP控件的生命周期有一些出入,我一时记不太清楚了,总之根据经验运行这个函数的时候可能Visual Tree还没有构建好,VisualTreeHelper...this.GetVisualDescendants().OfType().FirstOrDefault(c=>c.IsTabStop).Focus(); 这段代码的意思是找到此页面第一个可以接受键盘焦点的控件并让它获得焦点...,所以SecondTextBox获得了焦点。...在实时可视化树视图中可以看到有两个VisualTree,而Popup甚至不在里面,只有一个叫PopupRoot的类。具体可参考 Popup 概述 这篇文档。...结语 VisualTreeExtensions的代码很简单,我估计在UWP中也能使用,不过UWP已经在WindowsCommunityToolkit中提供了一个新的版本,只因为出于习惯,我还在使用Silverlight
"VerticalContentAlignment" Value="Stretch" /> 上面是BusyIndicator DefaultStyle的Setters,有一些细节是实现模板化控件需要注意的...: BusyContent BusyContent没有在依赖属性定义中的PropertyMetadata给出默认值,而是在Setter中给出,这是模板化控件中依赖属性的最佳做法。...IsTabStop 已经不厌其烦地提醒过复合类型控件要将IsTabStop设置为False,以便在使用键盘导航时其内容可以直接获得焦点。...ProgressRingStyle", StyleTargetType = typeof(ProgressRing))] IsTabStop和StyleTypedPropertyAttribute的介绍都可见我另一篇文章:了解模板化控件...幸运的是模板化控件最大的特色就是对修改UI是开放的,将来可以想办法修改。 ExtendBusyIndicator就算了,闹着玩的。 6.
小伙伴问我为什么他的选中的 Grid 无法接收到键盘消息,原因是在 UWP 中只有 Control 类才可以拿到键盘焦点,而 Grid 是 Panel 没有继承 Control 类所以 Grid 无法拿到焦点...需要在容器里面放一个继承 Control 的类,这个类可以接收键盘事件,通过路由事件让容器拿到键盘 在 UWP 中所有的 Panel 都没有继承 Control 类,而只有在 Control 才能获取焦点...只有键盘焦点才能收到键盘事件,也就是让 Grid 能接收 KeyDown 事件需要在 Grid 里面的元素拿到焦点 在 UWP 的所有 Control 都可以调用 Control.Focus 方法获取焦点...,所以可以让 Grid 在点击的时候设置 Grid 里面的控件焦点,这样在 Grid 里面的控件收到键盘事件时,可以通过路由事件让 Grid 收到键盘事件 定义一个空白的 Control 类,这个类主要是收到焦点...原因是在鼠标点击时,不仅会让 Grid 拿到鼠标焦点,此时的焦点将会在窗口的 ScrollViewer 也就是在 UWP 中窗口的滚动条里面,此时的键盘焦点也不再 Grid 里面。
UWP SDK中没提供这个控件,而是在UWP Community Toolkit中 提供 。它是个教科书式的入门级控件,代码简单,虽然仍然不尽如人意,但很适合用于学习如何自定义模版化控件。...这部分完全是面向初学者的,希望初学者通过Expander的源码学会一个基本的模板化控件应该如何构造。...2.4 OnApplyTemplate 模板化控件在加载ControlTemplate后会调用OnApplyTemplate(),Expander的OnApplyTemplate()实现了通常应有的实现...注意 Setter Property="IsTabStop" Value="False" 这句,对内容控件或复合控件,约定俗成都需要将IsTabStop设置成False,这是为了防止控件本身获得焦点。...如前言所说,这真的是个很好的入门级控件,很适合用于学习模板化控件。 5.
UI 元素的焦点有没有变化,以便了解 UWP 或 WPF 是否将此 UI 元素移出过视觉树。 结果如下图: 在 UWP 中,移动数据的元素焦点没有改变,Hash 值也没有改变。 ?...在 UWP 中,未被移动数据的元素 Hash 值没有改变。 ? 在 WPF 中,移动数据的元素焦点丢失,Hash 值已经改变。 ?...基本可以确定,UWP 的 ListBox 做了更多的优化,在根据 DataTemplate 生成控件时,一直在重用之前已经生成好的控件。...结论 UWP 比 WPF 对 ObservableCollection 的集合操作进行了更好的性能优化,在添加、删除、移动时会重用之前创建好的控件。...而在 WPF 中,则简单地创建和销毁这些控件——即便调用了 ObservableCollection 专有的 Move 方法也没有做更多的优化。
领取专属 10元无门槛券
手把手带您无忧上云