如何更改DrawingVisual的填充和描边颜色

3
我可以帮助您翻译中文。以下是需要翻译的内容:

我有一个 DrawingVisual 对象,我想更改它的填充和描边。

对于填充,我尝试了这个方法:

DrawingVisual MyDrawing = new DrawingVisual();
SetFill(Brushes.Red, MyDrawing.Drawing);

SetFill是什么:

private void SetFill(Brush fill, DrawingGroup group)
{
    foreach (Drawing drw in group.Children)
    {
        if (drw is DrawingGroup)
            SetFill(fill, drw as DrawingGroup);
        else if (drw is GeometryDrawing)
        {
            GeometryDrawing geo = drw as GeometryDrawing;
            geo.Brush = fill;

            using (DrawingContext context = MyDrawing.RenderOpen())
            {
                context.DrawDrawing(group);
            }
        }
    }
}

但这样可能会导致我的DrawingVisual被绘制到不同的位置,就好像变换没有被应用一样(对于MyDrawing)。
此外,如果我将这个指令改成:context.DrawDrawing(MyDrawing.Drawing); 就会出现奇怪的效果:第一次更改填充时什么也不会发生,而第二次更改填充时图形的位置不会改变,但填充会正确地改变。
我该怎么做?

你尝试过简单地递归设置GeometryDrawing.Brush而不需要重新绘制吗? - Clemens
是的,不幸的是,没有任何效果。 - gliderkite
很抱歉,您的“丑陋解决方案”可能会导致越来越多的绘图,因为每次调用SetFillEx时,您都会将一个现有的DrawingGroup放入新的DrawingGroup的Children集合中。 - Clemens
3个回答

2

解决您的问题(动态更改填充)的一个简单方法是使用自己的 SolidColorBrush 用于所有填充,并在需要时更改其 Color


你是指为每个DrawingVisual使用SolidColorBrush吗?我该如何改变呢?你能给一个小例子吗?另外,你看到我的编辑了吗? - gliderkite
我不能使用这个解决方案,因为我有成千上万的DrawingVisual,我宁愿不增加工作量;请参见我的最后编辑。 - gliderkite
什么工作量?只是一行代码而已。可能有误解:我不是指每个绘图都需要一个SolidColorBrush,而是总共只需要一个,一个用于所有的绘图。这很简单! - Clemens
刚看到你的新问题。这里的答案怎么样,你尝试过了吗? - Clemens
是的,你说我的“丑陋解决方案”时是正确的。我决定存储所有画笔,因为后来发现需要这样做才能完成其他任务。你是指这个问题吗?http://stackoverflow.com/questions/10715485/blank-screen-using-drawimage-method - gliderkite
显示剩余2条评论

2

您确实不需要重新绘制可视化图形。这应该可以解决问题。

private void SetFill(Brush fill, DrawingGroup group)
{
    foreach (Drawing drw in group.Children)
    {
        if (drw is DrawingGroup)
            SetFill(fill, drw as DrawingGroup);
        else if (drw is GeometryDrawing)
        {
            GeometryDrawing geo = drw as GeometryDrawing;
            geo.Brush = fill; // For changing FILL

            // We have to set Pen properties individually.
            // It does not work if we assign the whole "Pen" instance.
            geo.Pen.Brush = fill; 
            geo.Pen.Thickness = 1.0;
        }
    }
}

1

也许您已经解决了这个问题,但这是我的解决方案,也许可以帮到您。我有自己的DrawingVisual。它是新鲜的、没有经过很多测试的代码,但目前它运行得非常好:

public class MyDrawingVisual : DrawingVisual
{
    private bool myIsSelected = false;

    public VillageInfo VillageInfo { get; set; }

    public bool IsSelected 
    {
        get { return myIsSelected; }
        set
        {
            if (myIsSelected != value)
            {
                myIsSelected = value;

                // Retrieve the DrawingContext in order to create new drawing content.
                DrawingContext drawingContext = this.RenderOpen();

                // Create a rectangle and draw it in the DrawingContext.
                Rect rect = new Rect(new System.Windows.Point(VillageInfo.X + 0.1, VillageInfo.Y + 0.1), new System.Windows.Size(0.9, 0.9));
                drawingContext.DrawRectangle(new SolidColorBrush(myIsSelected ? Colors.White : VillageInfo.Color), (System.Windows.Media.Pen)null, rect);

                // Persist the drawing content.
                drawingContext.Close();
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接