WPF:刷新从frameworkelement派生的类
它的工作原理真的很奇怪。我有一些从框架元素派生的类。这是愚蠢的代码,因为我想让它变得更容易: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.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();
}
当我按下按钮时,奇怪的对象转到第一列(它在网格的开头呈现)。我的项目中有更多逻辑,我需要刷新奇怪的对象,但它应该仍在第二列中(在原来的位置)。
我做错了什么?
It works realy strange. I have some class derived from the framework element. It is stupid code because I want to make it easier :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;
}
}
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您对对象调用 Arrange 时,它会在您提供的相对于其父对象的位置重新绘制自身。由于它的父级是网格,因此 (0,0,size.Width,size.Height) 会将其放在左上角。
要解决您眼前的问题,您应该调用
InvalidateMeasure
,而不是测量和安排:但是,我认为您处理这个问题的方法略有错误。我认为你想要做的是重写
OnRender
来绘制你的控件。它与您使用DrawingVisual
所做的非常相似,除了您的FrameworkElement
是正在绘制的内容:我假设您将有一些 DependencyProperty 用于控制您的
Strange
类的绘制方式。如果您使用 FrameworkPropertyMetadata.AffectsRender 属性注册它们,它将自动导致类被重绘。例如,这将允许您为Strange
对象设置Color
,并且当您设置该属性时它将自动重绘: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
OnRender
to draw your control. It is very similar to what you're doing with theDrawingVisual
, except yourFrameworkElement
is what is being drawn:I assume that you would have some DependencyProperty's that you are using to control how your
Strange
class is drawn. If you register them with theFrameworkPropertyMetadata.AffectsRender
property, it will automatically cause the class to be redrawn. For instance, this will allow you to set aColor
for theStrange
object, and it will automatically get redrawn when you set the property: