3

我有重写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;
        }
    }
4

3 回答 3

3

恕我直言,最好的方法是在您使用的 DependencyProperties 上指定它们会影响渲染。

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

于 2013-03-28T15:47:07.670 回答
2

最快的当然是走肮脏的方式并做到这一点

(DataContext as INotifyPropertyChanged).PropertyChanged += OnPropertiesChanged

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

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

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

于 2013-03-28T15:47:00.510 回答
1

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

如果大小保持不变,使用某些保留模式绘图对象可以OnRender(). 例如,DrawingGroupWriteableBitmap, 和RenderTargetBitmap都可以在输出OnRender()更新。

在大多数情况下,您将创建一个DrawingGroup“backingStore”,在此期间将其输出OnRender(),然后您可以随时通过执行backingStore.Open()并将新的绘图命令放入DrawingGroup.

于 2017-06-11T02:28:41.507 回答