WPF 装饰器有什么意义?

2024-01-24

我最近为我的公司开发了一个绘图组件,其中包含一个画布,您可以在上面通过单击并拖动来绘制某些形状。对于每个形状,我在其 AdornerLayer 上放置了两个装饰器:一个用于增加命中检测(基本上是一个会超出形状边界几个像素的透明矩形),另一个用于调整大小(角上的四个拇指控件)。

但是,在实现组件的一些功能时,我遇到了很多问题,所有这些问题都与装饰器相关。

  • 他们捕获了所有预览事件,因为它们位于画布本身之外的另一个视觉树中,这是出乎意料的,但我找到了一个解决方法,即使我不太喜欢它。使用 AdornerDecorator 并没有解决这个问题,我实现的选择装饰器是预览事件的黑洞。

  • 当我在 Canvas 上实现形状的 z-index 操作(发送到后面、带到前面等)时,正如您所期望的那样,使用 Panel.SetZIndex 效果很好。但是,装饰器位于另一个视觉树中!因此它们没有受到影响,并且选择装饰器仍然位于所有其他形状之上,即使这些形状位于选择装饰器正在检测命中的形状之上。 例如: 形状 1,选择装饰器 1。 形状 2、选择装饰器 2。 Shape1 位于 Shape2 的顶部(稍后添加到画布),因此它与 Shape2 重叠。因此,SelectionAdorner1 会检测到对它的点击。我操纵 ZIndex 将其发送到后面,现在 Shape2 位于顶部并与 Shape1 重叠。我单击 Shape2 顶部,但该单击是由 SelectionAdorner1 而不是 SelectionAdorner2 检测到的。 这特别烦人。因此,显然由于装饰器位于另一个视觉树上,因此它们不尊重 ZIndexes。我尝试通过在形状的 ZIndex 和其 SelectionAdorner 的 ZIndex 之间创建 DataBinding(以及手动设置)来解决该问题。但这并没有解决问题。改变装饰器的 ZIndex 并不会影响它们在屏幕上的显示方式,也许我错过了一些东西,但它不应该真的这么难,因为装饰器应该让事情变得更容易。我能想到的唯一解决方案是手动删除所有装饰器,然后再一一手动添加它们,最后添加应该位于顶部的装饰器。虽然这有点迟缓,但它确实有效。

  • 接下来,装饰者不尊重 ClipToBounds!我在我正在绘制的画布中设置了 ClipToBounds=true ,效果很好,但该死的装饰器仍然可以工作!这个问题的解决方案相对轻松,我只是在每个形状的顶部添加了一个 AdornerDecorator。在我看来,这不是一个理想的解决方案,但足够简单。

  • 装饰者并不总是对在其装饰元素上执行的 LayoutTransforms 做出良好的反应。我在画布顶部有一个面板,它实现缩放和平移功能。它使用动画来使放大和缩小更加平滑。但是使用动画导致我的装饰者变得疯狂!第一次缩放时,他们会简单地忽略调整大小并保持相同的大小和位置,在第二次缩放时,他们会缩放到previous装饰元素的大小。那没有任何意义!我能找到的唯一解决方案是禁用动画,谢天谢地,这有效

我不太记得我遇到了哪些其他问题,但这足以让我想知道装饰器的有用性,并且我正在认真考虑不在我的下一个项目中使用它们,该项目与我描述的项目类似。

那么,谁能告诉我使用这些看似有用但非常烦人的东西可能有什么优点呢?


我想你已经知道你的问题的答案了。它们在某些方面节省了时间,但在其他方面却造成了问题。如果您要使用各种 UserControl 来编写此设计器行为,您会发现自己编写了大量样板控件类来包装您实际想要编辑的元素。另一方面,如果您尝试编写单独的编辑控件并智能地覆盖它们,您将编写样板代码以保持它们的位置和大小同步。您采用的方法(使用装饰器)产生了大量(相当样板的)代码来管理事件。

虽然装饰器可能不是最好的工具特别的任务,它们仍然是执行其他更简单任务的有用工具。我最近写了一个类似的“设计表面”,装饰器是两件作品的天赐之物:

  1. 拖放行为。当我拖动不同的元素时,它们需要有不同的视觉预览;使用自定义装饰器和数据模板可以非常轻松地完成此任务。
  2. 选择矩形或“套索”。当您在 Windows 桌面上按住鼠标左键并四处拖动指针时,您可以看到类似的内容。它创建一个可以选择多个元素的半透明框。我几乎可以使用装饰层立即创建此行为,而创建我自己的自定义控件会导致大量不必要的簿记。

我认为您在项目中发现的是,您可能一直在使用装饰器来尝试完成太多任务。但不要把婴儿和洗澡水一起倒掉——它们在某些情况下仍然非常有用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF 装饰器有什么意义? 的相关文章

  • 缓冲数据库游标中的数据,同时保持 UI 响应

    我有一个已填充的数据库目录和一个可用于检索对象的游标 这个目录显然可能非常大 我想做的是使用反应式用户界面缓冲数据 同时保持 UI 数据绑定和响应 我按照步骤操作here http www interact sw co uk iangblo
  • 是否有 .NET 库或 API 可以与 IIS 配置数据库交互/编辑它?

    或者我是否坚持使用自己的 XML 切割 功能 我想创建一个小型任务托盘应用程序 以便我可以快速将虚拟目录重新指向硬盘上的几个文件夹之一 一点背景 我的开发机器上的代码库有 3 个不同的 svn 分支 Current Production B
  • 异步WCF调用来保存线程?

    In 另一个问题 https stackoverflow com q 19731600 279516 建议我发送异步网络请求 而不是在后台线程上发送同步请求 原因是为了不浪费一根线 我试图理解这是怎么回事 这是最初的做法 我可以理解这里怎么
  • .net 中的 deflate、gzip 和 zlib 的一个库

    首先 我们来定义一些容易混淆的术语 deflate compression algorithm zlib header deflate trailer gzip header deflate trailer 我正在寻找一个基本上可以让我执行
  • 从架构上来说,我应该如何用更易于管理的内容替换非常大的 switch 语句?

    EDIT 1 忘记添加嵌套属性曲线球 UPDATE 我选择了 mtazva 的答案 因为这是我的具体案例的首选解决方案 回想起来 我用一个非常具体的例子提出了一个一般性问题 我相信这最终让每个人 或者也许只是我 对问题到底是什么感到困惑 我
  • 使用实体框架从 2 个表返回数据

    我正在使用 MVC3 和实体框架 但我需要来自不同表的更多数据 通常我会做这样的事情来从表中获取数据 Table Users id username 在代码中我会做这样的事情来获取所有用户 public static IEnumerable
  • WPF DataGrid 验证/绑定模式错误

    我创建了一个非常简单的新项目 仅测试 Microsoft WPF DataGrid 行为 不涉及其他 我只使用标准的 DataGrid
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 如何使正则表达式匹配不区分大小写?

    我有以下正则表达式加拿大的邮政编码 http en wikipedia org wiki Postal codes in Canada ABCEGHJKLMNPRSTVXY 1 d 1 A Z 1 d 1 A Z 1 d 1 它工作正常 但
  • 使用 Amazon SQS 的 .net 应用程序示例

    我正在寻找一个示例 Net 应用程序 该应用程序会持续检查 Amazon SQS 是否有新消息 并在发现新消息时执行一项操作并将其从队列中删除 我的目标是让一个在 EC2 上运行的应用程序监视我的 SQS 队列中的新消息 当找到一条消息时
  • MongoDb 注册类映射

    我有以下代码 我希望 MiscellaneousData 覆盖抽象的 MiscellaneousDataBase 然而 IdMemberMap 总是出现空值 使用独立的 正常 类是可行的 if BsonClassMap IsClassMap
  • 标准化 C# 中的换行符

    我有一个数据流 可能包含 r n r n n r 或它们的任意组合 有没有一种简单的方法来规范化数据 使它们全部变成 r n 对 使显示更加一致 所以会产生这种转换表 r gt r n n gt r n n n gt r n r n n r
  • .NET 标准与 .NET 核心

    我已经了解了 NET Standard 和 NET Core 之间的区别 但我真的不知道区别是什么 或者何时选择 NET Standard 库项目以及何时选择 NET Core 库项目 我读到 NET Standard 是为了确保一组 AP
  • 如何将 Razor 视图转换为字符串?

    我想使用我的 Razor 视图作为某种发送电子邮件的模板 所以我想将我的模板 保存 在视图中 将其作为字符串读入控制器 进行一些必要的替换 然后发送它 我有有效的解决方案 我的模板作为 HTML 页面托管在某处 但我想将其放入我的应用程序中
  • 如何使用 .NET 以编程方式沙箱进程

    我计划设计一个系统 本质上允许用户在我的机器上运行 PHP Ruby 等脚本代码 我想将它们放入沙箱中 以防止它们访问机器的关键方面 哪些 NET API 可用于此目的 我计划从主流程创建一个子流程 并希望以编程方式从主流程中沙箱该子流程
  • ASP.NET MVC:如何可靠地获取当前请求的真实URL?

    现在我有一个 MVC 应用程序运行在http 127 0 0 1 8081 http 127 0 0 1 8081 它实际上在 Azure 计算模拟器中运行 浏览器位置栏清楚地显示端口号为 8081 然而 Request Url and R
  • 限制 LDAP 查询中返回的属性

    如何限制通过 System DirectoryServices 在 LDAP 查询中返回的属性 我一直在使用 DirectorySearcher 并将我想要的属性添加到 DirectorySearcher PropertiesToLoad
  • 如何从作为 UWP 运行的 WPF 应用程序处理文件激活?

    我有一个WPF我想要处理文件激活的应用程序 我找到了通过向注册表添加特定值来解决问题的解决方案 问题是最终的应用程序应该是UWP应用程序 我正在使用桌面桥来执行此操作 如果应用程序运行为UWP 它无法到达注册表来设置这些特定值 有没有其他方
  • 合并两个(或更多)PDF

    背景 我需要为我的销售人员提供每周报告包 该包包含几个 5 10 个水晶报告 Problem 我想允许用户运行所有报告并且只运行单个报告 我想我可以通过创建报告然后执行以下操作来做到这一点 List

随机推荐

  • 服务导致 SCM 错误“报告了无效的当前状态 0”

    我编写了一个小型服务 充当本地网络服务器 为了编写服务 我遵循了MSDN 上的教程 https msdn microsoft com en us library zt39148a v vs 110 aspx 如何使用编写服务ServiceB
  • 如何组合 pandas 中的行

    我有一个这样的数据集 df pd DataFrame a a b b a b a b b a 我想合并前两行并获得这样的数据集 df pd DataFrame a a b b a b a b b a 没有规则 但前两行 我不知道如何组合行
  • 在 Pycharm 之外运行脚本时找不到导入?

    我有一个这样构建的项目 main py 从子文件夹导入脚本 如下所示 from controllers available balances controller import available balances controller 子
  • 我需要什么 K.clear_session() 和 del 模型(Keras with Tensorflow-gpu)?

    我在做什么我正在使用 Keras 和 Tensorflow gpu 作为后端来训练和使用卷积神经网络 CNN 进行图像分类 我正在使用什么 PyCharm 社区 2018 1 2 Python 2 7 和 3 5 但不能同时使用 乌班图16
  • 黄瓜的路由问题

    我正在使用 Rails 3 和 Cucumber 除了这个小问题之外一切都很顺利 Given I am on the edit automobile page No route matches controller gt automobil
  • 模块未出现在 jupyter 中

    我在将模块导入 jupyter 时遇到问题 我做了以下事情 创建虚拟环境 激活它 下面的所有内容都在我的 venv 上下文中 安装雅虎财经模块 pip install yfinance 打开 python 控制台并导入它来测试是否工作 gt
  • 如何转储所有_G表内容

    我想转储 G 表 在 G 表中还有其他表也转储 内联表 我想要一个好的格式 我有一个例子 但使用它转储 G表有一些问题 function print table node to make output beautiful local fun
  • 将垂直滚动从 UIScrollView 转发到同级 UITableView

    我有一个具有以下层次结构的视图控制器 视图控制器 UIScrollView 可水平滚动 UITableView 可垂直滚动 我想转发我的垂直卷轴UIScrollView给兄弟姐妹UITableView 这样当用户向上滚动时UIScrollV
  • Kubernetes 集群上的粘性会话

    目前 我正在尝试在 Google Cloud 上创建一个 Kubernetes 集群 其中包含两个负载均衡器 一个用于后端 在 Spring boot 中 另一个用于前端 在 Angular 中 其中每个服务 负载均衡器 与 2 个副本 p
  • 使用 cURL 获取 HTTP 标头并保存到变量

    我用它来获取 XML 提要和 HTTP 标头 Initiate the curl session ch curl init Set the URL curl setopt ch CURLOPT URL url Allow the heade
  • 如何将 Chrome 开发者控制台停靠在左侧?

    我知道您可以单击垂直省略号按钮 然后选择停靠在底部 右侧或分离 但有人知道如何停靠在左侧吗 目前我必须分离然后手动调整大小和调整 这很烦人 Edit 我将保留这个问题 直到有人说服谷歌添加左对接 或者有人找出黑客 发现或构建扩展以使其正常工
  • 带有 Activity 和子 Fragment 的导航抽屉

    我有一个Activity A a 列表片段 P and 2 碎片 Q and R 当应用程序启动时 A已创建 加载P 根据用户点击的内容 将其替换为Q or R 现在通过引用this https developer android com
  • 如何突出显示 Ionic 列表中的选定项目

    我在屏幕上填充了一个项目列表 只想在列表视图中突出显示所选项目 请帮助
  • 关于不阻塞 GUI 线程的 MessageBox.Show 替换的建议?

    不久前 我遇到了一种情况 我们需要向用户显示消息框以获取通知 但我们无法使用 MessageBox Show 因为它会阻塞 GUI 线程 因此当对话框处于活动状态时 屏幕上的任何内容都不会更新 关于替代方案有什么建议吗 我当时编写了一个替代
  • Linux 和 Windows 上 html 中的 javascript 导入区分大小写

    我有以下内容 测试 html test js var Test test 问题是为什么它在 Windows 上工作而在 Linux 上不起作用 换句话说 为什么 linux 对于导入区分大小写 但 window 不区分 如何在 Linux
  • SQL Server数据通过网络发送时以什么格式序列化?

    我问这个问题的原因是因为我们计划将大量 几 GB 数据从 SQL Server 数据库读取到 Net 应用程序进行处理 我想知道为每条记录计算多少空间开销 以估计对网络流量的影响 例如 一条记录由 5 个整数组成 即 4 5 20 字节数据
  • Codeigniter result_array()何时返回单维或多维数组?

    返回 query gt result array 时有时我会得到多个像这样的单个数组 Array user id gt 32 username gt johnd cat id gt 7 Array user id gt 33 usernam
  • Action Script 中的 JSON:如何获取 JSON 对象的属性和值?

    假设我有这个 JSON 并且假设属性可能会改变 srcLocation pc filename name fileext jpg url 首先我想获取它们的所有属性 srcLocation 文件名等 并使用我得到的属性我想获得相应的值 我怎
  • 如何舍入到某个浮点精度?

    我认为这是一个简单的问题 我想 a 1 154648126486416 成为 a 1 154 and not a 1 15000000000 在不使用的情况下我该如何做到这一点format bank 你可以这样做 a floor a 100
  • WPF 装饰器有什么意义?

    我最近为我的公司开发了一个绘图组件 其中包含一个画布 您可以在上面通过单击并拖动来绘制某些形状 对于每个形状 我在其 AdornerLayer 上放置了两个装饰器 一个用于增加命中检测 基本上是一个会超出形状边界几个像素的透明矩形 另一个用