It works realy strange. I have some class derived from the framework element. It is stupid code because I want to make it easier 😛
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;
}
}
Next I put this class to the Grid.
<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();
}
When I pressed the Button, the Strange object went to the first column (it is rendered at the begining of the Grid). I have more logic in my project and I need to refresh Strange object, but it should be still in the second column (in the place where it was).
What I did wrong?
When you call Arrange on the object, it is redrawing itself at the location you provide, relative to its parent. Since its parent is the grid, (0,0,size.Width,size.Height) will put it in the upper-left hand corner.
To fix your immediate problem, instead of measuring, and arranging, you should just call
InvalidateMeasure:However, I think you are approaching this problem slightly wrong. I think what you want to do is to override
OnRenderto draw your control. It is very similar to what you’re doing with theDrawingVisual, except yourFrameworkElementis what is being drawn:I assume that you would have some DependencyProperty’s that you are using to control how your
Strangeclass is drawn. If you register them with theFrameworkPropertyMetadata.AffectsRenderproperty, it will automatically cause the class to be redrawn. For instance, this will allow you to set aColorfor theStrangeobject, and it will automatically get redrawn when you set the property: