设置WPF依赖项属性而不触发事件

时间:2020-03-06 14:56:13  来源:igfitidea点击:

我需要在代码中的控件(Slider.Value)上设置依赖项属性,而不会触发ValueChanged事件(因为我设置了值,而不是用户)。在WPF中处理这种情况的最佳方法是什么?

为了澄清起见,我想做的是将WPF滑块连接到WinForms用户控件。当前在我的应用程序中,我有一个ValueChanged事件处理程序,该处理程序通过方法调用将滑块值传递给WinForms控件。 WinForms控件(实际上是本机OpenGL窗口的包装)需要能够根据其内部计算动态地更改滑块。为此,我使用了一个滑块(ISlider)的抽象形式,在我的应用程序中实例化了该滑块的WPF风格,然后通过WinForms用户控件上的.NET属性将其基础的句柄传递给WinForms控件。所有这些当前都有效,只是当内部逻辑决定需要更改滑块时,它调用ISlider :: SetPos(),然后更改WPF滑块,然后触发滑块上的ValueChanged事件和处理程序对于该事件,将提取滑块的位置,并将其传递到首先触发该事件的WinForms控件中。 ligaz和Alan Le的建议似乎都应该奏效,但我不确定我是否会以最佳方式解决这个问题。

解决方案

一种可能的解决方案是从Slider派生并重写OnValueChanged(...)。当我们不想引发该事件时,我们应该什么都不做,否则我们应该调用基本实现。

这是一个简单的解决方法/黑客。添加一个布尔值以跟踪是否更改了设置,例如说" IsChangedByMe"。当我们在代码中更改依赖项属性时,请将布尔值设置为true。在ValueChanged事件中,如果IsChangedByMe为true,则不执行任何操作。

我们确定要这么做吗?如果有一个UI数据绑定到该属性,并且我们允许在不触发ValueChanged事件的情况下更改值,那么我们将很快以UI不再与数据同步的方式结束。

对于滑块,想象用户将其放置在75%的位置。现在,代码在后台将其更改为10%,但不显示更改通知。它仍然在屏幕上看起来像是75%(因为没有告知它已更改),但是正在被运行的代码用作10%。听起来像是造成混乱的秘诀。