You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何强制DrawingVisual重绘?实例化后能否修改该对象

核心结论

实例化后的DrawingVisual完全可以修改——你可以再次调用它的RenderOpen()方法重新绘制内容,或者直接替换为新的DrawingVisual实例。

你的代码问题分析

当前代码无法更新的原因是:

  • _visual仅在构造函数中初始化一次,调用InvalidateVisual()只会触发UIElement重绘,但你没有更新_visual的内容或替换实例,WPF会复用旧的渲染结果。
  • InvalidateVisual()的作用是通知WPF元素需要重新渲染,但如果视觉子元素没有变化,界面不会更新。
修复方案(两种可选)

方案1:替换整个DrawingVisual实例

修改RandomSquare类,添加更新方法并正确管理视觉子元素:

public class RandomSquare : UIElement
{
    private DrawingVisual _visual;

    public RandomSquare()
    {
        _visual = GetRandomSquare();
        AddVisualChild(_visual); // 注册视觉子元素
    }

    private DrawingVisual GetRandomSquare()
    {
        Random rnd = new Random();
        int xy = rnd.Next(200);
        int size = rnd.Next(200);

        DrawingVisual visual = new DrawingVisual();
        using (DrawingContext context = visual.RenderOpen())
        {
            context.DrawRectangle(Brushes.AliceBlue, new Pen(Brushes.DarkBlue, 1), new Rect(xy, xy, size, size));
        }
        return visual;
    }

    // 添加更新方法
    public void GenerateNewSquare()
    {
        RemoveVisualChild(_visual); // 移除旧视觉子元素
        _visual = GetRandomSquare(); // 生成新实例
        AddVisualChild(_visual); // 注册新视觉子元素
        InvalidateVisual(); // 触发重绘
    }

    protected override int VisualChildrenCount => 1;

    protected override Visual GetVisualChild(int index)
    {
        if (index != 0) throw new ArgumentOutOfRangeException(nameof(index));
        return _visual;
    }
}

修改按钮点击事件:

private void Button_Click(object sender, RoutedEventArgs e)
{
    randomSqare.GenerateNewSquare();
}

方案2:直接修改现有DrawingVisual的内容

无需替换实例,直接重新绘制现有_visual的内容:

public class RandomSquare : UIElement
{
    private DrawingVisual _visual;
    private Random _rnd = new Random(); // 避免每次创建新Random导致重复值

    public RandomSquare()
    {
        _visual = new DrawingVisual();
        AddVisualChild(_visual);
        UpdateSquare();
    }

    private void UpdateSquare()
    {
        int xy = _rnd.Next(200);
        int size = _rnd.Next(200);
        
        using (DrawingContext context = _visual.RenderOpen())
        {
            context.DrawRectangle(Brushes.AliceBlue, new Pen(Brushes.DarkBlue, 1), new Rect(xy, xy, size, size));
        }
    }

    public void GenerateNewSquare()
    {
        UpdateSquare(); // 直接修改现有DrawingVisual内容
        InvalidateVisual();
    }

    protected override int VisualChildrenCount => 1;

    protected override Visual GetVisualChild(int index)
    {
        if (index != 0) throw new ArgumentOutOfRangeException(nameof(index));
        return _visual;
    }
}

内容的提问来源于stack exchange,提问作者Mohammed Kasfy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 08:54:23