Marvin's Blog【程式人生】

Ability will never catch up with the demand for it

10 Nov 2019

XAML API 学习笔记:Control

Windows.UI.Xaml.Controls.Control继承自FrameworkElement,是ContentControl、UserControl以及ItemsControl的基类。Control定义了一个ControlTemplate辖属,可以用来控制和调整Control内容的显示方式。

或许可以把ControlTemplate看成是编程语言中的lambda,本身作为参数,可以被传递,然后在距离创建点很远的地方被调用。

Control通过Template辖属(类型为来ControlTemplate)设置内容的显示方式。

需要注意的是,虽然UserControl是从Control派生的。但是UserControl主要是用于自定义不需要做视觉状态保存的控件使用。另外虽然它有Template属性,但是其实是无效的。

XAML使用的是XML作为描述语言。XML没有控制命令,描述不了循环迭代。除此之外,XML跟LISP还是有不少相似之处的。伴对象和伴辖属其实可以作为它的上下文来使用。

Control通常有隐含样式(Implicit Style),提供默认的控制模板。这样一来,就算FrameworkElement.Style没有被设置,Control也有自己的默认样式可以使用。默认样式随WinRT发布,以二进制的方式存储在dll中。Control的DefaultStyleKey含有隐含样式的键名。DefaultStyleKey是采用保护型(protected)访问控制,所以只能在派生类中修改。非派生类中DefaultStyleKey不可访问和修改。但是也不是没有折衷的办法,可以在XAML的资源字典中定义样式,并且把样式的TargetType指定为你想修改的Control的类型。在XAML解析的时候,这些样式会比隐含样式更优先被使用。

通过视觉状态(Visual State)变化,可以给用户提供信息,表明当前正常发生的操作。通过连图板(Storyboard)动画,可以短期或者无期限修改视觉元素的辖属,来让他们呈现出某种状态。视觉状态通常也在控制模板中定义,并且有自己的名字,可以通过GoToState来加载。视觉状态也有分组,每组中只有一个状态可以被激活,避免冲突。如果视觉状态切换到其他分组,也就意味着当前分组对视觉元素的影响结束了。

Control主要目的是为了和用户交互,而交互的手段之一就是键盘击键。规则很简单,拥有焦点的Control可以获得键盘击键。Control的Focus方法可以让它主动获得焦点。Control的IsEnabled和IsTabStop用来控制Control是否能够获得焦点。能够获得焦点的Control参与Tab焦点易换。FocusState告知Control的焦点信息(是用户设置的,还是程序通过Focus方法设置的)。

在Framework级别,定义了一些原生事件,比如 PointerPressed,这样可以通过OnPointerPressed来修改其行为。除了原生事件,还有后生事件。比如ButtonBase会把某些OnPointerPressed和OnKeyDown事件转化为Click这种后生事件,来简化Control的处理逻辑。

可以获得焦点的控件,必须具有下列特征:

  • Visibility is Visible
  • IsEnabled is true
  • IsTabStop is true
  • 其控制模板已经加载(Loaded),控件连接上visual tree。

如果不想让控件获取焦点,可以将IsTabStop置false;如果不想让控件获得焦点,并且在视觉上有所呈现,可以将IsEnabled为false。

焦点切换会产生LostFocus或者GotFocus事件。虽然GetFocusedElement可以返回获得焦点的元素,但是LostFocus或者GotFocus事件是异步处理的,被事件处理器捕获的时候,焦点元素已经发生变化。

Control定义了一些跟字体呈现有关的属性:

  • Foreground
  • FontFamily
  • FontSize
  • FontStretch
  • FontStyle
  • FontWeight

并不是所有的Control都能够或者都需要显示文字。上述的属性是为了让控制模板能够使用{TemplateBinding} markup extension来绑定上述属性到模板的文本元素部件。Control的这些属性还能够被ContentPresenter继承。

Control有一堆派生的类型:

  • AppBarSeparator
  • ContentControl
  • DatePicker
  • Hub
  • HubSection
  • ItemsControl
  • MenuFlyoutItemBase
  • PasswordBox
  • ProgressRing
  • RangeBase
  • RichEditBox
  • SearchBox
  • SemanticZoom
  • TextBox
  • Thumb
  • TimePicker
  • ToggleSwitch
  • UserControl

同时Control还有一些附着辖属:

  • IsTemplateFocusTarget
  • IsTemplateKeyTipTarget

(完)

comments powered by Disqus