如何使依赖属性上的可视化无效?

时间:2013-03-28 15:27:08

标签: .net wpf controls dependency-properties

我使用重写的 OnRender 方法进行自定义控制。 我希望在更改任何依赖项属性时使控件无效(包括父类型的属性)。 我怎么能这样做?

修改

作为解决方案,我发现我可以使用'影响渲染'配置并检查OnLayoutUpdated是否有所改变。

FrameworkPropertyMetadata.AffectsRender

private void OnLayoutUpdated(object sender, EventArgs e)
    {
        int result = (CornerRadius != null ? CornerRadius.GetHashCode() : 0);
        result = (result * PrimeHashNumber) ^ (IsSelected.GetHashCode());
        result = (result * PrimeHashNumber) ^ (IsReadCornerRadiusFromConfig.GetHashCode());
        result = (result * PrimeHashNumber) ^ (IsReadBorderThicknessFromConfig.GetHashCode());
        result = (result * PrimeHashNumber) ^ (SelectedColor!=null?SelectedColor.GetHashCode():0);
        result = (result * PrimeHashNumber) ^ (Background != null ? Background.GetHashCode() : 0);
        result = (result * PrimeHashNumber) ^ (BorderBrush != null ? BorderBrush.GetHashCode() : 0);

        if (lastHash != result)
        {
            this.InvalidateVisual();
            lastHash = result;
        }
    }

3 个答案:

答案 0 :(得分:3)

imho最好的方法是在你使用的DependencyProperties上指定它们会影响渲染。

请参阅FrameworkPropertyMetadata.AffectsRender:http://msdn.microsoft.com/en-us/library/system.windows.frameworkpropertymetadata.aspx

答案 1 :(得分:2)

最快的当然是肮脏的方式并且这样做

(DataContext as INotifyPropertyChanged).PropertyChanged += OnPropertiesChanged

private void OnPropertiesChanged(sender, args)
{
    InvalidateVisual();
}

但我强烈建议你不要做那样的事情。另一方面,imho更好的解决方案有点受限制。尝试更改自定义依赖项属性,使它们与呈现相关,因为您可以在创建依赖项属性时提供标志AffectsRender。 现在你说的是“来自父类型的属性”我没有得到那个部分,但我想你的意思是一个带有子视图模型的父视图模型。如果您相应地设计属性,这无关紧要。 如果由于某种原因该解决方案不起作用,您可以在视图模型上仅使用一个属性,在视图中使用AffectsRender标志绑定到依赖项属性,并在视图重绘时将其设置在视图模型逻辑中,但是再次,这是肮脏的方式。

另外,不要太过于想要使用OnRender方法进行大量绘制,我们在大型应用程序中使用WPF,如果我们使用OnRender,我们可能有一两个地方,其他一切都是通过样式和模板。

答案 2 :(得分:0)

如果您的控件的大小没有变化,InvalidateVisual()非常昂贵,因为它会导致控制树的完全重新布局。

如果大小保持不变,那么在OnRender()期间输出之后可以更新某些保留模式绘图对象更高效。例如,在DrawingGroup期间输出之后,WriteableBitmapRenderTargetBitmapOnRender()都可以更新

在大多数情况下,你会创建一个DrawingGroup" backingStore",在OnRender()期间输出它,然后你可以随时更新你的控件的视觉效果{{1并将新的绘图命令放入backingStore.Open()