【发布时间】:2017-08-29 17:40:21
【问题描述】:
我正在构建将用于显示图块地图的自定义用户控件,作为我选择 ScrollableControl 的基类,因为我希望在我的控件中有滚动条。
我已经成功创建了负责绘制只需要的元素的绘制逻辑。
现在我正在尝试添加将始终在同一个位置可见的静态文本(在我的例子中,左上角带有红色文本的白色框):
这在上面的 gif 中不是很明显,但是当我使用鼠标或滚动条滚动时,那个白框会闪烁和跳跃。
我的问题是我应该如何更改我的代码以在该可滚动内容之上具有可滚动内容和固定位置内容?
ScrollableControl 作为基类是不错的选择吗?
下面是我的代码:
class TestControl : ScrollableControl
{
private int _tileWidth = 40;
private int _tileHeight = 40;
private int _tilesX = 20;
private int _tilesY = 20;
public TestControl()
{
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.Opaque, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
UpdateStyles();
ResizeRedraw = true;
AutoScrollMinSize = new Size(_tilesX * _tileWidth, _tilesY * _tileHeight);
Scroll += (sender, args) => { Invalidate(); };
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillRectangle(new SolidBrush(BackColor), ClientRectangle);
e.Graphics.TranslateTransform(AutoScrollPosition.X, AutoScrollPosition.Y);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
var offsetX = (AutoScrollPosition.X * -1) / _tileWidth;
var offsetY = (AutoScrollPosition.Y * -1) / _tileHeight;
var visibleX = Width / _tileWidth + 2;
var visibleY = Height / _tileHeight + 2;
var x = Math.Min(visibleX + offsetX, _tilesX);
var y = Math.Min(visibleY + offsetY, _tilesY);
for (var i = offsetX; i < x; i++)
{
for (var j = offsetY; j < y; j++)
{
e.Graphics.FillRectangle(Brushes.Beige, new Rectangle(i*_tileWidth, j*_tileHeight, _tileWidth, _tileHeight));
e.Graphics.DrawString(string.Format("{0}:{1}", i, j), Font, Brushes.Black, new Rectangle(i * _tileWidth, j * _tileHeight, _tileWidth, _tileHeight));
}
}
using (var p = new Pen(Color.Black))
{
for (var i = offsetX + 1; i < x; i++)
{
e.Graphics.DrawLine(p, i*_tileWidth, 0, i*_tileWidth, y*_tileHeight);
}
for (var i = offsetY + 1; i < y; i++)
{
e.Graphics.DrawLine(p, 0, i*_tileHeight, x*_tileWidth, i*_tileHeight);
}
}
e.Graphics.FillRectangle(Brushes.White, AutoScrollPosition.X * -1, AutoScrollPosition.Y * -1, 35, 14);
e.Graphics.DrawString("TEST", DefaultFont, new SolidBrush(Color.Red), AutoScrollPosition.X * -1, AutoScrollPosition.Y * -1);
}
}
编辑:
我进行了一些搜索,发现具有类似功能的 UserControl - https://www.codeproject.com/Articles/16009/A-Much-Easier-to-Use-ListView 并在控件作者博客http://objectlistview.sourceforge.net/cs/blog1.html#blog-overlays 上阅读了更多内容后,我发现他正在使用位于控件顶部的透明表单。
我真的很想避免这种情况,但仍然有覆盖在我的控制之上。
【问题讨论】:
标签: c# .net winforms user-controls