2011-08-12 45 views
1

它的工作很奇怪。我有一些從框架元素派生的類。這是愚蠢的代碼,因爲我想使它更容易:PWPF:從frameworkelement派生的刷新類

public class Strange : FrameworkElement 
{ 
    public DrawingVisual Visual; 

    public Strange() 
    { 
     Visual = CreateDrawingVisualRectangle(); 
    } 

    protected override Visual GetVisualChild(int index) 
    { 
     return Visual; 
    } 
    protected override int VisualChildrenCount 
    { 
     get 
     { 
      return 1; 
     } 
    } 

    // Create a DrawingVisual that contains a rectangle. 
    public DrawingVisual CreateDrawingVisualRectangle() 
    { 

     var drawingVisual = new DrawingVisual(); 

     DrawingContext drawingContext = drawingVisual.RenderOpen(); 
     var rect = new Rect(new Point(0, 0), new Size(100, 100)); 
     drawingContext.DrawRectangle(Brushes.Red, null, rect); 
     drawingContext.Close(); 

     return drawingVisual; 
    } 
} 

接下來,我把這個類的網格。

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="Auto"/> 
     <ColumnDefinition Width="*"/> 
    </Grid.ColumnDefinitions> 
    <Button Click="Button_Click">Change Color</Button> 
    <Test:Strange Grid.Column="1" x:Name="strange"/> 
</Grid> 

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     strange.Visual = strange.CreateDrawingVisualRectangle(); 
     var size = new Size(strange.ActualWidth, strange.ActualHeight); 
     strange.Measure(size); 
     strange.Arrange(new Rect(size)); 
     strange.UpdateLayout(); 
    } 

當我按下按鈕時,奇怪對象轉到第一列(它在網格開始時呈現)。我在我的項目中有更多的邏輯,我需要刷新奇怪的對象,但它應該仍然在第二列(在它所在的位置)。

我做錯了什麼?

回答

4

當您在對象上調用Arrange時,它將在您提供的位置相對於其父對象重繪自己。由於其父母是網格,因此(0,0,size.Width,size.Height)會將其放在左上角。

要解決立即解決問題,而不是測量和安排,你應該只調用InvalidateMeasure

strange.Visual = strange.CreateDrawingVisualRectangle(); 
strange.InvalidateMeasure(); 

不過,我覺得你處理這個問題稍有不妥。我認爲你想要做的就是重寫OnRender來繪製你的控制。這是非常相似,你與DrawingVisual做什麼,除了你FrameworkElement是什麼正在繪製:

protected override void OnRender(DrawingContext dc) 
{    
    var rect = new Rect(new Point(0, 0), new Size(100, 100)); 
    dc.DrawRectangle(Brushes.Red, null, rect); 
} 

我以爲你會有些的DependencyProperty的您正在使用來控制你的Strange類是如何得出。如果使用FrameworkPropertyMetadata.AffectsRender屬性註冊它們,它將自動導致類重新繪製。例如,這將允許您爲Strange對象設置Color,並且在設置屬性時它將自動重繪:

public class Strange : FrameworkElement 
{ 
    #region Color Dependency Property 
    public static readonly DependencyProperty ColorProperty = 
     DependencyProperty.Register(
     "Color", 
     typeof(Color), 
     typeof(Strange), 
     new FrameworkPropertyMetadata(Colors.Red, 
      FrameworkPropertyMetadataOptions.AffectsRender)); 

    public Color Color 
    { 
     get { return (Color)GetValue(ColorProperty); } 
     set { SetValue(ColorProperty, value); } 
    } 
    #endregion 

    protected override void OnRender(DrawingContext dc) 
    {    
     var rect = new Rect(new Point(0, 0), new Size(100, 100)); 
     dc.DrawRectangle(new SolidColorBrush(Color), null, rect); 
    } 
}