如何让DrawString在Y轴负缩放因子下正常渲染刻度右侧文本?
解决Y轴反转时DrawString文本倒置的问题
我之前也碰到过类似坐标系变换导致文本渲染异常的情况,你的问题根源在于Y轴的负缩放变换会同步作用于文本的渲染方向,所以文字会跟着倒置。下面给你两个实用的解决方案:
方法1:临时重置Graphics变换(推荐)
在绘制文本前,先保存当前Graphics的变换状态,然后重置变换,计算出适配默认坐标系的文本位置,绘制完成后再恢复原来的变换。这样既能保留原有刻度线的绘制逻辑,又能让文本正常显示。
修改后的代码如下:
using (Pen pen = new Pen(_color)) using (Font drawFont = new Font("Arial", 16)) using (SolidBrush drawBrush = new SolidBrush(Color.Black)) { pen.Width = 1F / e.Graphics.DpiX; // 获取控件高度,用于转换Y坐标 float controlHeight = this.TimeSeriesPanelControl.ClientSize.Height; foreach (float tick in this.TimeSeriesPanelControl.YTicks) { e.Graphics.DrawLine(pen, right, tick, right + 10, tick); // 保存当前Graphics的变换状态 var originalState = e.Graphics.Save(); try { // 重置变换,回到默认的左上角原点坐标系 e.Graphics.ResetTransform(); // 转换Y坐标:你的坐标系原点在左下角,默认在左上角,所以用控件高度减去tick值 // 额外调整文本垂直位置,让它和刻度线居中对齐 float textY = controlHeight - tick - drawFont.Height / 2; e.Graphics.DrawString(tick.ToString("F2"), drawFont, drawBrush, right + 15, textY); } finally { // 恢复原来的变换,不影响后续绘图操作 e.Graphics.Restore(originalState); } } }
方法2:给文本单独应用反向变换
另一种思路是针对文本单独抵消全局的Y负缩放,不过需要计算文本的基准点,示例代码如下:
using (Pen pen = new Pen(_color)) using (Font drawFont = new Font("Arial", 16)) using (SolidBrush drawBrush = new SolidBrush(Color.Black)) { pen.Width = 1F / e.Graphics.DpiX; StringFormat format = new StringFormat(StringFormatFlags.NoClip) { LineAlignment = StringAlignment.Center // 让文本和刻度线垂直居中对齐 }; foreach (float tick in this.TimeSeriesPanelControl.YTicks) { e.Graphics.DrawLine(pen, right, tick, right + 10, tick); // 保存当前变换状态 var originalState = e.Graphics.Save(); try { // 应用反向缩放,抵消全局的Y负变换 e.Graphics.ScaleTransform(1, -1); // 计算文本绘制位置,反向平移Y坐标 PointF textPos = new PointF(right + 15, -tick); e.Graphics.DrawString(tick.ToString("F2"), drawFont, drawBrush, textPos, format); } finally { e.Graphics.Restore(originalState); } } }
额外提示
建议使用StringFormat调整文本对齐方式,让文本和刻度线垂直居中,视觉效果会更专业。另外,Save()和Restore()一定要配对使用,避免破坏后续的绘图逻辑。
内容的提问来源于stack exchange,提问作者user3351749
相关产品推荐
相关产品推荐

