WritePixels在Timer Tick事件中无法更新WriteableBitmap求助
解决WriteableBitmap在Timer Tick事件中无法更新的问题
核心问题分析
你的代码在Timer外部正常但Tick事件内失效,大概率是线程调度或UI更新逻辑的问题,以下是针对性的解决方案:
1. 替换Timer类型为DispatcherTimer
WPF的UI元素只能在Dispatcher(UI线程)中更新,如果使用System.Timers.Timer,其Tick事件会在后台线程触发,直接操作WriteableBitmap可能导致UI无法感知变化。换成DispatcherTimer确保事件在UI线程执行:
// 初始化时改用DispatcherTimer private DispatcherTimer timer = new DispatcherTimer(); // 在构造函数或初始化方法中设置 timer.Interval = TimeSpan.FromMilliseconds(1); // 按需调整刷新间隔 timer.Tick += Timer_Tick; timer.Start();
2. 避免重复设置Source
全局的targetBitmap只需在初始化时绑定一次到targetControl.Source,无需每次Tick都重复赋值。重复设置相同引用会让UI跳过重绘逻辑:
// 初始化时执行一次即可 targetControl.Source = targetBitmap;
3. 修正像素索引与边界判断
你的边界判断pixelIndex >= 100 * 100 * 4错误:100×100的图像总像素数是10000,pixelIndex是按像素计数的,应该判断是否超过总像素数;同时要正确计算字节数组的起始索引,避免每次写入整个数组:
private void Timer_Tick(object sender, EventArgs e) { // 边界判断:总像素数为100*100,而非字节数 if (pixelIndex >= 100 * 100) { timer.Stop(); return; } int x = pixelIndex % 100; int y = pixelIndex / 100; // 计算当前像素在字节数组中的起始位置 int byteStartIndex = y * stride + x * 4; Int32Rect rect = new Int32Rect(x, y, 1, 1); // 仅写入当前像素的4个字节数据 targetBitmap.WritePixels(rect, pixels1d, stride, byteStartIndex); pixelIndex++; }
4. 可选:手动触发重绘
如果上述调整后仍不生效,可在WritePixels后添加手动刷新逻辑:
targetBitmap.Invalidate();
额外排查点
- 确认
WriteableBitmap的PixelFormat与pixels1d的字节格式匹配(比如Bgra32对应每个像素4字节,顺序为蓝、绿、红、Alpha) - 检查
stride计算是否正确:stride = targetBitmap.PixelWidth * (targetBitmap.Format.BitsPerPixel / 8)
内容的提问来源于stack exchange,提问作者TomQ
相关产品推荐
相关产品推荐

