首页 > 其他分享 >第3章 自定义控件2

第3章 自定义控件2

时间:2023-07-10 17:33:55浏览次数:41  
标签:控件 自定义 附加 ProgressBar progress ProcessStage 属性

3 强大的附加属性

所以你正在构建一个令人惊喜的新应用程序,你需要一种在现有控件中没有直接支持的行为。你确信除了创建子类并为自己创建一堆工作外,没有其他方法来扩展现有的控件功能。是时候创建子类了,对吗?

WPF提供了一项创新功能,称为附加属性,它可以用于向现有控件添加行为。这些新属性不是在正在扩展的控件上定义的,而是在一个单独的对象上定义的(通常是DependencyObject)。因此,我们得到一个定义附加属性的源对象和一个将这些属性附加到其上的目标对象。目标对象是在源中包含的新功能扩展的对象。当在目标对象上设置附加属性时,源会触发属性更改事件。事件处理程序会传递有关目标以及属性的新旧值的信息。

通过连接属性更改处理程序,我们可以通过调用目标上的方法、更改属性和侦听事件来添加其他行为。在第6章“附加属性的力量”中,我们会更详细地介绍使用附加属性的例子。请记住,附加属性只是扩展功能的一种手段;原始目标控件仍然需要被视为“黑盒子”,不能修改其内部。

假设您想表示特定工作流程的进度。虽然进度在内部以百分比表示,但用户界面指南要求以阶段方式显示进度,共有五个阶段,每个阶段表示完成100%的1/20。

这可以通过使用进度条的控制模板(ControlTemplate)和附加属性的有趣用法的组合来实现。控制模板定义了ProgressBar的可视化效果。触发器用于突出显示当前阶段。由于触发器仅仅能够使用单个值进行比较(例如,当PropertyX等于ValueY时触发),而不是使用范围比较,我们不能直接使用ProgressBar的Value属性来突出显示当前阶段。



一个很好的方法是实际上增强ProgressBar,使其具有一个Stage属性。这将使控件扩展的其余部分变得更容易。为了做到这一点,我们需要一个帮助类ProcessStageHelper,它将进度值的范围映射到自定义的ProcessStage枚举。我们根据当前的进度值选择正确的ProcessStage。可以在代码清单3.1中看到这一点。

ProcessStageHelper类公开了两个附加属性:一个用于接收进度值,另一个用于提供一个只读的ProcessStage枚举值。

public class ProcessStageHelper : DependencyObject
{
public static readonly DependencyProperty
ProcessCompletionProperty = DependencyProperty.RegisterAttached(
”ProcessCompletion”, typeof(double),
typeof(ProcessStageHelper), new PropertyMetadata(0.0,
OnProcessCompletionChanged));
private static readonly DependencyPropertyKey
ProcessStagePropertyKey =
DependencyProperty.RegisterAttachedReadOnly(
”ProcessStage”, typeof(ProcessStage),
typeof(ProcessStageHelper),
new PropertyMetadata(ProcessStage.Stage1));
public static readonly DependencyProperty ProcessStageProperty =
ProcessStagePropertyKey.DependencyProperty;
private static void OnProcessCompletionChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
double progress = (double)e.NewValue;
ProgressBar bar = (d as FrameworkElement).TemplatedParent
as ProgressBar;
if (progress >= 0 && progress < 20)
bar.SetValue(ProcessStagePropertyKey, ProcessStage.Stage1);
if (progress >= 20 && progress < 40)

bar.SetValue(ProcessStagePropertyKey, ProcessStage.Stage2);
if (progress >= 40 && progress < 60)
bar.SetValue(ProcessStagePropertyKey, ProcessStage.Stage3);
if (progress >= 60 && progress < 80)
bar.SetValue(ProcessStagePropertyKey, ProcessStage.Stage4);
if (progress >= 80 && progress <= 100)
bar.SetValue(ProcessStagePropertyKey, ProcessStage.Stage5);
}

 前面的代码比必要的复杂,只是为了帮助说明可以向现有类添加的额外功能。OnProcessCompletionChanged处理程序设置了ProcessStage只读附加属性。由于这个只读属性附加到了ProgressBar类,因此可以在ControlTemplate.Triggers部分使用它来根据当前工作流程阶段提供自定义的UI,如代码清单3.2所示。

<ControlTemplate x:Key=”ProcessStageTemplate”
TargetType=”ProgressBar”>
...
...
<ControlTemplate.Triggers>
<Trigger
Property=”Chapter_CustCtrl:ProcessStageHelper.ProcessStage”
Value=”Stage1”>
<Setter Property=”Fill”
Value=”{StaticResource SelectedStageBrush}”
TargetName=”Stage1” />
<Setter Property=”Stroke”
Value=”#bb2d00”
TargetName=”Stage1” />
</Trigger>
<Trigger Property=”Chapter_CustCtrl:ProcessStageHelper.ProcessStage”
Value=”Stage2”>
<Setter Property=”Fill”
Value=”{StaticResource SelectedStageBrush}”
TargetName=”Stage2” />
<Setter Property=”Stroke”
Value=”#bb2d00”
TargetName=”Stage2” />
</Trigger>
<Trigger Property=”Chapter_CustCtrl:ProcessStageHelper.ProcessStage”
Value=”Stage3”>
<Setter Property=”Fill”
Value=”{StaticResource SelectedStageBrush}”
TargetName=”Stage3” />
<Setter Property=”Stroke”
Value=”#bb2d00”
TargetName=”Stage3” />
</Trigger>
...
...
</ControlTemplate.Triggers>
</ControlTemplate>

在3.2清单中,我们创建了多个触发器。每个触发器在流程阶段设置为特定值时被触发。然后,该代码可以设置相应“阶段”框的填充和描边属性。 请记住,这只是一个小例子,展示了您可以在不创建自己的控件的情况下扩展控件行为和视觉效果的方式之一。

标签:控件,自定义,附加,ProgressBar,progress,ProcessStage,属性
From: https://www.cnblogs.com/cbaa/p/17541792.html

相关文章

  • Camstar表格自定义写js,实现单元格合并。
     效果: ......
  • app直播源代码,自定义顶部搜索栏显示隐藏
    app直播源代码,自定义顶部搜索栏显示隐藏1、wxml代码 <viewclass="bar-box"style="height:{{navBarHeight}}px;">  <viewwx:if="{{show}}"class="level"style="margin-top:{{barHeight}}px;">    <viewclass=&......
  • elementui el-draw自定义拖拽指令
    一、问题引入场景:el-draw抽屉高度(宽度)可拖拽二、解决方案使用vue指令,el-draw打开后,插入一个元素,绑定鼠标事件实现拖拽主要代码如下/***el-drawer拖拽高度指令*/Vue.directive('el-drawer-drag-height',{bind(el,binding,vnode,oldVnode){......
  • 十三、控件
    1.QLineEdit单行输入框1.1示例仿登录界面  2.QDialog对话框2.1属性Modal:如果为true时,弹出此对话框,其他界面变黑不可点击。setWindowFlag(Qt::FramelessWindowHint);设置对话框失去上边的状态栏。2.2示例仿支付界面 部分代码1this->setWindowFlag(......
  • 通用曲线控件定制之重点难点篇(附源码,功能丰富灵活) 浮云E绘图
    ​ 上篇已经介绍通用曲线控件源码定制之设计实现,详细描述了通用曲线控件的功能部件及其结构关系,并且实现了核心类的源码,本文由浮云E绘图继续介绍通用曲线控件定制开发的重点和难点,并附完整源码。 一.曲线控件源码类使用流程根据上文通用曲线控件源码定制之设计实现篇可知曲......
  • 按单元格填充颜色或字体颜色统计数据的自定义函数
    参考网络代码,自己写了二个通用的自定义函数,用于统计不同颜色的单元格数值或个数。1FunctionSumColor(rngAsRange,cellColorAsRange,NAsByte)AsDouble23'输入=SumColor(A1:A10,A1,0),其中A1:A10是统计的范围,A1是统计的颜色所在的单元格,0表示按照背景......
  • iOS 开发入门 3-基础: iOS 视图控件 UIView
    相信大家通过前两篇文章已经大致了解了OC当中的数据组成部分,今天正式开始咱们iOS开发最主要的一个环节视图控件的使用.在正式开始讲解UIView之前我们需要先了解下什么是视图控件.其实视图控件的概念很好理解,比如说我们在打开某一应用的时候在手机上所看到的所有界面组成元素都是......
  • python创建类似于wx.EVT_BUTTON这样的自定义事件
    想要创建类似于wx.EVT_BUTTON这样的自定义事件,可以通过定义一个继承自wx.PyEvent的子类,并在其中添加自定义的事件类型。下面是一个示例代码:importwx#创建自定义事件类型MY_EVENT_TYPE=wx.NewEventType()EVT_MY_EVENT=wx.PyEventBinder(MY_EVENT_TYPE,1)#创建自定义......
  • Element Plus el-table 自定义合并行和列
    原文链接:ElementPlusel-table自定义合并行和列前言目标效果是将表格行数据中某个属性值相同的项合并到一起,效果如下:<el-table:data="tableData":span-method="spanMethod"style="width:100%"><el-table-columnprop="StoAlias"label="节点名称&quo......
  • 【项目实战功能】自定义注解实现代码的执行耗时记录
    博主介绍:✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,阿里云专家博主,华为云云享专家✌......