2013-07-10 115 views
1

我有一个类继承帆布具有以下依赖属性更新依赖属性当子属性已更新

public class StorageCanvas : Canvas 
{ 
public readonly static DependencyProperty StorageProperty = DependencyProperty.Register(
    "Storage", 
    typeof(Polygon), 
    typeof(StorageCanvas)); 

public Polygon Storage 
{ 
    get { return (Polygon) GetValue(StorageProperty); } 
    set { SetValue(StorageProperty, value); } 
} 
} 

我可以以某种方式使依赖属性“更新”的时候,Storage多边形Points已经改变/更新,而不是要求多边形替换为新的实例?

+1

你是什么意思的更新?重绘?重新评估?重新布局?谁在更改存储。每次更新财产时盲目更新并不明智。但是您可以使用Invalidate方法为自己触发,如InvalidateVisual。你也可以改变属性的元数据来自动调用Invalidate函数,如果它们被改变了,这对你的存储不起作用,因为它通过调用setter来工作。 – dowhilefor

+0

我想,你可以使用依赖属性'Callbacks'和'Validation'。有关更多信息,请参见[msdn](http://msdn.microsoft.com/zh-cn/library/ms745795.aspx)。 –

+0

@dowhilefor无论多边形的“点数”发生变化,我都希望在画布上重绘多边形。 –

回答

2

Polygon.PointsPointCollection,所以你可以只订阅Changed事件,然后调用InvalidateVisual()如果任何个人PointStorage由@dowhilefor

public class StorageCanvas : Canvas { 
    public static readonly DependencyProperty StorageProperty = DependencyProperty.Register(
    "Storage", 
    typeof(Polygon), 
    typeof(StorageCanvas), 
    new FrameworkPropertyMetadata(null, PropertyChangedCallback)); 

    public Polygon Storage { 
    get { 
     return (Polygon)GetValue(StorageProperty); 
    } 
    set { 
     SetValue(StorageProperty, value); 
    } 
    } 

    private static void PropertyChangedCallback(
    DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) { 
    var currentStorageCanvas = dependencyObject as StorageCanvas; 
    if (currentStorageCanvas == null) 
     return; 
    var oldPolygon = args.OldValue as Polygon; 
    if (oldPolygon != null) 
     oldPolygon.Points.Changed -= currentStorageCanvas.PointsOnChanged; 
    var newPolygon = args.NewValue as Polygon; 
    if (newPolygon == null) 
     return; 
    newPolygon.Points.Changed += currentStorageCanvas.PointsOnChanged; 

    // Just adding the following to test if updates are fine. 
    currentStorageCanvas.Children.Clear(); 
    currentStorageCanvas.Children.Add(newPolygon); 
    } 

    private void PointsOnChanged(object sender, EventArgs eventArgs) { 
    InvalidateVisual(); 
    } 
} 

提出所以现在改变,而不实际重新创建整个对象,InvalidateVisual()将被解雇。

这个概念只是订阅了Changed事件PointsCollection。根据您的要求和逻辑,您是否需要根据自己的需求来解决问题,这是否正确。

+0

'InvalidateVisual()'是非常重的触发重绘的重量方式。如果控件的大小没有改变,可以使用AffectsRender或者在OnRender()中为DrawingContext添加一个DrawingGroup,然后在任何时候你可以使用DrawingGroup.Open()来改变视觉效果。 –