c#、winform
需求:
鼠标出panel后,panel中的一个控件消失,鼠标金panel后,panel中的那个控件出现,控件要响应mousedown、mouseup、mousemove。实现再panel中拖动。
bug:
mousedown有时候响应,有时候不响应
原因:
不是很清楚,但是把鼠标从panel中出去的隐藏控件操作去掉,mousedown就每次可以响应了,追查中。。。
代码:
自己实现一个scrollpanel,scrollpanel中包含一个全高全宽的panel,然后使用贴图的vScrollBar拖动,hScrollBar还没做
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace myWinForm.customControl
{
class cs_ScrollPanel : Panel
{
private int hMinIndex = 0;
private int hMaxIndex = 100;
private int hCurPos = 0;
private int hWidth = 20;
private int hRate = 5;
private int vMinIndex = 0;
private int vMaxIndex = 100;
private int vCurPos = 0;
private int vHeight = 20;
private int vRate = 5;
private Panel innerPanel = null;
private PictureBox vScrollBar;
private PictureBox hScrollBar;
private int scrollSize_m = 10;
private int mouseState = 0;
private Point startPosition;
public HQ_ScrollPanel(Panel thePanel)
{
innerPanel = thePanel;
initControls();
Resize += new EventHandler(HQ_ScrollPanel_Resize);
MouseEnter += new EventHandler(HQ_ScrollPanel_MouseEnter);
MouseLeave += new EventHandler(HQ_ScrollPanel_MouseLeave);
MouseWheel += new MouseEventHandler(HQ_ScrollPanel_MouseWheel);
//MouseDown += new MouseEventHandler(vScorllBar_MouseDown);
//MouseUp += new MouseEventHandler(vScorllBar_MouseUp);
//MouseMove += new MouseEventHandler(vScorllBar_MouseMove);
}
public void setvMaxIndex(int height)
{
vMaxIndex = height;
HQ_ScrollPanel_Resize(null, null);
}
private void HQ_ScrollPanel_MouseWheel(object sender, MouseEventArgs e)
{
if (null != innerPanel)
{
innerPanel.Location = new Point(innerPanel.Location.X, innerPanel.Location.Y + e.Delta / 10);
}
}
private void HQ_ScrollPanel_MouseLeave(object sender, EventArgs e)
{
if (null != vScrollBar)
{
//vScrollBar会删,vScorllBar有时会不响应mouseDown事件fuck
//vScrollBar.Hide();
}
if (null != hScrollBar)
{
//hScrollBar.Hide();
}
}
private void HQ_ScrollPanel_MouseEnter(object sender, EventArgs e)
{
if (null != vScrollBar)
{
if (vMaxIndex < vMinIndex || (vMaxIndex - vMinIndex) < Height)
{
//vScrollBar.Hide();
}
else
{
vScrollBar.Show();
}
}
if (null != hScrollBar)
{
if (hMaxIndex < hMinIndex || (hMaxIndex - hMinIndex) < Width)
{
//hScrollBar.Hide();
}
else
{
hScrollBar.Show();
}
}
}
private void HQ_ScrollPanel_Resize(object sender, EventArgs e)
{
if (null != vScrollBar)
{
vMaxIndex = innerPanel.Height;
initvScrollInt(vMaxIndex - vMinIndex, Height);
vScrollBar.Size = new Size(scrollSize_m, vHeight);
vScrollBar.Location = new Point(Width - scrollSize_m, vCurPos / vRate);
resetVScrollImage();
}
if (null != hScrollBar)
{
hMaxIndex = innerPanel.Width;
inithScrollInt(hMaxIndex - hMinIndex, Width);
hScrollBar.Size = new Size(hWidth, scrollSize_m);
hScrollBar.Location = new Point(hCurPos / hRate, Height - scrollSize_m);
resetHScrollImage();
}
}
private void initvScrollInt(int innerSize, int outerSize)
{
int minInt = 20;
if (innerSize < outerSize)
{
minInt = outerSize;
vHeight = minInt;
return;
}
int overSize = innerSize - outerSize; //越界距离
int blankSize = overSize / vRate; //滚动条空白距离
if (blankSize + minInt > outerSize)
{
blankSize = outerSize - minInt;
vRate = (overSize + blankSize - 1) / blankSize;
vHeight = minInt;
return;
}
minInt = outerSize - blankSize;
vHeight = minInt;
}
private void inithScrollInt(int innerSize, int outerSize)
{
int minInt = 20;
if (innerSize < outerSize)
{
minInt = outerSize;
hWidth = minInt;
return;
}
int overSize = innerSize - outerSize; //越界距离
int blankSize = overSize / hRate; //滚动条空白距离
if (blankSize > outerSize + minInt)
{
blankSize = outerSize - minInt;
hRate = (overSize + blankSize - 1) / blankSize;
hWidth = minInt;
return;
}
minInt = innerSize - blankSize;
hWidth = minInt;
}
private void resetVScrollImage()
{
Image image = Image.FromFile(".\\res\\vScrollItem.png");
Image bgImage = new Bitmap(vScrollBar.Width, vScrollBar.Height);
Graphics gp = Graphics.FromImage(bgImage);
//上半圆
gp.DrawImage(image, new Rectangle(0, 0, vScrollBar.Width, vScrollBar.Width * 2),
new Rectangle(0, 0, vScrollBar.Width, vScrollBar.Width * 2), GraphicsUnit.Pixel);
//下半圆
gp.DrawImage(image, new Rectangle(0, vScrollBar.Height - vScrollBar.Width * 2, vScrollBar.Width, vScrollBar.Width * 2),
new Rectangle(0, image.Height - vScrollBar.Width * 2, vScrollBar.Width, vScrollBar.Width * 2), GraphicsUnit.Pixel);
//中间填充
gp.DrawImage(image, new Rectangle(0, vScrollBar.Width * 2, vScrollBar.Width, vScrollBar.Height - vScrollBar.Width * 4),
new Rectangle(0, vScrollBar.Width * 2, vScrollBar.Width, image.Height - vScrollBar.Width * 4), GraphicsUnit.Pixel);
vScrollBar.Image = bgImage;
}
private void resetHScrollImage()
{
Image image = Image.FromFile(".\\res\\hScrollItem.png");
Console.WriteLine("reset hscrollbar size {0} {1}", image.Size, hScrollBar.Size);
Image bgImage = new Bitmap(hScrollBar.Width, hScrollBar.Height);
Graphics gp = Graphics.FromImage(bgImage);
//左半圆
gp.DrawImage(image, new Rectangle(0, 0, hScrollBar.Height * 2, hScrollBar.Height),
new Rectangle(0, 0, hScrollBar.Height * 2, hScrollBar.Height), GraphicsUnit.Pixel);
//右半圆
gp.DrawImage(image, new Rectangle(hScrollBar.Width - hScrollBar.Height * 2, 0, hScrollBar.Height * 2, hScrollBar.Height),
new Rectangle(image.Width - hScrollBar.Height * 2, 0, hScrollBar.Height * 2, hScrollBar.Height), GraphicsUnit.Pixel);
//中间填充
gp.DrawImage(image, new Rectangle(hScrollBar.Height * 2, 0, hScrollBar.Width - hScrollBar.Height * 4, hScrollBar.Height),
new Rectangle(hScrollBar.Height * 2, 0, image.Width - hScrollBar.Height * 4, hScrollBar.Height), GraphicsUnit.Pixel);
hScrollBar.Image = bgImage;
}
private void initControls()
{
initvScrollInt(vMaxIndex - vMinIndex, Height);
vScrollBar = new PictureBox();
vScrollBar.Location = new Point(Width - scrollSize_m, 0);
vScrollBar.Size = new Size(scrollSize_m, vHeight);
vScrollBar.SizeMode = PictureBoxSizeMode.StretchImage;
vScrollBar.MouseDown += new MouseEventHandler(vScorllBar_MouseDown);
vScrollBar.MouseUp += new MouseEventHandler(vScorllBar_MouseUp);
vScrollBar.MouseMove += new MouseEventHandler(vScorllBar_MouseMove);
//vScrollBar.BackColor = Color.FromArgb(0xff, 0xff, 0xff);
Controls.Add(vScrollBar);
resetVScrollImage();
inithScrollInt(hMaxIndex - hMinIndex, Width);
hScrollBar = new PictureBox();
hScrollBar.Location = new Point(0, Height - scrollSize_m);
hScrollBar.Size = new Size(scrollSize_m, hWidth);
hScrollBar.SizeMode = PictureBoxSizeMode.StretchImage;
Controls.Add(hScrollBar);
resetHScrollImage();
if (null != innerPanel)
{
Controls.Add(innerPanel);
innerPanel.Resize += new EventHandler(innerPanel_Resize);
}
AutoScroll = false;
}
private void innerPanel_Resize(object sender, EventArgs e)
{
vMaxIndex = innerPanel.Height;
HQ_ScrollPanel_Resize(null, null);
}
private void vScorllBar_MouseMove(object sender, MouseEventArgs e)
{
if (1 == mouseState)
{
int newVPos = vScrollBar.Location.Y + e.Location.Y - startPosition.Y;
if (newVPos < 0)
{
newVPos = 0;
}
else if (newVPos + vHeight > Height)
{
newVPos = Height - vHeight;
}
vScrollBar.Location = new Point(vScrollBar.Location.X, newVPos);
if (null != innerPanel)
{
innerPanel.Location = new Point(innerPanel.Location.X, vMinIndex - vScrollBar.Location.Y * vRate);
vCurPos = vScrollBar.Location.Y * vRate;
}
}
}
private void vScorllBar_MouseUp(object sender, MouseEventArgs e)
{
mouseState = 0;
startPosition = new Point(0, 0);
}
private void vScorllBar_MouseDown(object sender, MouseEventArgs e)
{
Console.WriteLine("mouse down..");
mouseState = 1;
startPosition = e.Location;
}
}
}