我使用重写的 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;
}
}
答案 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
期间输出之后,WriteableBitmap
,RenderTargetBitmap
和OnRender()
都可以更新。
在大多数情况下,你会创建一个DrawingGroup
" backingStore",在OnRender()
期间输出它,然后你可以随时更新你的控件的视觉效果{{1并将新的绘图命令放入backingStore.Open()
。