我正在構建用於顯示平鋪貼圖的自定義用戶控件,因爲我選擇的基礎類爲ScrollableControl
,因爲我想在我的控件中使用滾動條。使用帶有固定位置文本的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);
}
}
編輯:
我搜索了一下,發現用戶控件具有類似的功能 - https://www.codeproject.com/Articles/16009/A-Much-Easier-to-Use-ListView和閱讀略偏上控制的作者博客http://objectlistview.sourceforge.net/cs/blog1.html#blog-overlays後,我發現,他正在使用位於控制之上的透明窗體。 我真的很想避免這種情況,但仍然覆蓋在我的控制之上。
非常感謝您的回覆。再次您的代碼幫助(一如既往)!現在,當我使用滾動條時,我可以獲得平滑滾動,並且我的標籤位於頂部。不幸的是,當我用鼠標滾輪滾動沒有任何改變時,我的白色盒子仍然跳動。可以使用鼠標滾輪滾動嗎? – Misiu
我已經爲'OnMouseWheel'添加覆蓋:'LockWindowUpdate(Handle); base.OnMouseWheel(e); LockWindowUpdate(IntPtr.Zero); Update();'這解決了我用鼠標滾輪的問題。請檢查並更新您的答案。這樣,有相同問題的人將有工作解決方案。 – Misiu
我注意到,當在'OnScroll'' e.Type' =='ThumbPosition'裏面時,我調整控件的大小(整個窗體)時會出現奇怪的行爲http://i63.tinypic.com/2zfikbr.gif我已經管理(e.Type!= ScrollEventType.Last)LockWindowUpdate(this.Handle);'如果(e.Type!= ScrollEventType.Last && e.Type!= ScrollEventType.ThumbPosition)LockWindowUpdate(Handle );'你能否再次看看這個並更新你的答案? – Misiu