它真的很奇怪。我有一些派生自框架元素的类。这是愚蠢的代码,因为我想让它变得更容易:P
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>
<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();
}
当我按下Button时,Strange对象转到第一列(它在Grid的开头呈现)。我的项目中有更多逻辑,我需要刷新Strange对象,但它应该仍然在第二列(在它所在的位置)。
我做错了什么?
答案 0 :(得分: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
属性注册它们,它将自动重新绘制类。例如,这将允许您为Color
对象设置Strange
,并在设置属性时自动重绘:
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);
}
}