I made a scrollable panel like this:
private void button3_Click(object sender, EventArgs e)
{
Form f2 = new Form();
f2.Size = new Size(400, 300);
f2.AutoScroll = false;
Panel pan = new Panel();
pan.Size = new Size(600, 100);
pan.AutoScroll = false;
for (int i = 1; i <= 10; i++)
{
Button b = new Button();
b.Text = "B" + (i);
b.Name = "button_" + (i);
b.Left = (b.Width + 12) * (i - 1);
b.Parent = pan;
pan.Parent = f2;
f2.Show();
}
}
private void panel1_MouseWheel(object sender, MouseEventArgs e)
{
Form2 frm = new Form2();
panel1.Top += e.Delta > 0 ? 10 : -10;
if (panel1.Top > 0)
panel1.Top = 0;
else if (panel1.Top <= panel1.Parent.Height)
panel1.Top = panel1.Parent.Height;
Console.WriteLine("panel2.top:" + panel1.Top);
}
This is the full code of that panel, panel1 = pan...
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
pPt = e.Location;
}
public void panel1_MouseMove(object sender, MouseEventArgs e)
{
Console.WriteLine("panel2.top:" + panel1.Top);
if (e.Button.HasFlag(MouseButtons.Left))
{
Form2 frm = new Form2();
panel1.Top += e.Y - pPt.Y;
if (panel1.Top > 0)
panel1.Top = 0;
else if (panel1.Top <= panel1.Parent.Height)
panel1.Top = panel1.Parent.Height;
}
}
And you can scroll it by dragging the panel with the mouse but the problem is it looks like this:
And I want to don't go higher than button1 or lower than the last button.
Tweak this method: you need to "pin" the panel so it doesn't move below the top and above the bottom - because mouse wheel deltas are events you will continuously receive. You have to manually decide when to ignore them
private void panel1_MouseWheel(object sender, MouseEventArgs e)
{
Form2 frm = new Form2();
panel1.Top += e.Delta > 0 ? 10 : -10;
// tweak this
if (panel1.Top > 0) panel1.Top = 0;
else if (panel1.Bottom <= panel1.Parent.Height) panel1.Bottom = panel1.Parent.Height;
Console.WriteLine("panel2.top:" + panel1.Top);
}
Also, the above will work when the panel you are scrolling is "Taller" than the viewport (the form itself). You might need to tweak further when the panel is smaller than the form - so just test a few cases.
You also need to pay attention to the Resize event so your panel has the correct Top property when someone expands the container form.
We can Get or set the upper limit of values of the scrollable range with
ScrollBar.Maximum Property
An example is as follows.
The following example assumes that you have created a Form, added a PictureBox to the Form, and added a horizontal HScrollBar and a vertical VScrollBar to the PictureBox. This code example is part of a larger example provided for the ScrollBar class overview.
In this example, the Maximum property is set to the size of the Image plus the size of the scrollbar if it is visible plus an adjustment factor of the size of the LargeChange property.
You must add references to the System.Drawing and System.Windows.Forms namespaces to run this example.
public void SetScrollBarValues()
{
//Set the following scrollbar properties:
//Minimum: Set to 0
//SmallChange and LargeChange: Per UI guidelines, these must be set
// relative to the size of the view that the user sees, not to
// the total size including the unseen part. In this example,
// these must be set relative to the picture box, not to the image.
//Maximum: Calculate in steps:
//Step 1: The maximum to scroll is the size of the unseen part.
//Step 2: Add the size of visible scrollbars if necessary.
//Step 3: Add an adjustment factor of ScrollBar.LargeChange.
//Configure the horizontal scrollbar
//---------------------------------------------
if (this.hScrollBar1.Visible)
{
this.hScrollBar1.Minimum = 0;
this.hScrollBar1.SmallChange = this.pictureBox1.Width / 20;
this.hScrollBar1.LargeChange = this.pictureBox1.Width / 10;
this.hScrollBar1.Maximum = this.pictureBox1.Image.Size.Width - pictureBox1.ClientSize.Width; //step 1
if (this.vScrollBar1.Visible) //step 2
{
this.hScrollBar1.Maximum += this.vScrollBar1.Width;
}
this.hScrollBar1.Maximum += this.hScrollBar1.LargeChange; //step 3
}
//Configure the vertical scrollbar
//---------------------------------------------
if (this.vScrollBar1.Visible)
{
this.vScrollBar1.Minimum = 0;
this.vScrollBar1.SmallChange = this.pictureBox1.Height / 20;
this.vScrollBar1.LargeChange = this.pictureBox1.Height / 10;
this.vScrollBar1.Maximum = this.pictureBox1.Image.Size.Height - pictureBox1.ClientSize.Height; //step 1
if (this.hScrollBar1.Visible) //step 2
{
this.vScrollBar1.Maximum += this.hScrollBar1.Height;
}
this.vScrollBar1.Maximum += this.vScrollBar1.LargeChange; //step 3
}
}
Hope you can change the code accordingly to set the maximum scrollable space.:)
Related
Here is my key code:
using System;
using System.Windows.Forms;
namespace Scroller
{
public partial class Form1 : Form
{
int i, j;
bool k = false;
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = "Time:"+ System.DateTime.Now.ToString();
i--;
j = i + this.Width;
if (i < this.Width && i > 0)
{
label1.Left = i;
}
else
if (i < 0 && k == false)
{
label1.Left = i;
k = true;
}
else
if (i < 0 && k == true)
{
label1.Left = j;
k = false;
}
if (i < 0 - label1.Width)
{
i = this.Width - label1.Width;
}
}
private void Form1_Load(object sender, EventArgs e)
{
label1.Text = "Time:"+ System.DateTime.Now.ToString();
i = this.Width - label1.Width;
label1.Left = i;
}
}
}
The effect that I want to make is the whole time string move right to left. When a pixel of the text disappear on the left side (because it is out of the form's left border),the pixel will shows on the right side.
In other words, the effect can't be make by delete the first character of string and append it to the last.
I knew that it will be easier to use two label to do it. Set one's location in the form and hide the other right by the form. Move them in the same time.
When the first label hit the left border of the form, the second hit the right border of the form. And the first one move out, the second move in. Until the second totally move in, reset their x location.
But I just want to use one label. So I chose to quickly switch the label's location, and try to "cheat" user's eye. The problem is when the label switch between left and right, it flash very obviously. Even though I set timer's interval below 20,the problem still exist.
Could you help me dissolve the flash problem or enlighten me other ways which can just use one label and one timer to make the effect I need?
Thanks. If I didn't describer my problem clear enough or need more code, please let me know.
I don't think you can work out the flashing problem changing the label's location in a windows form.
Another solution would be to set the label width the same size as the form width, make the label text fill all the width using spaces and make the timer always get the last character and put it on the beginning of the string.
Sample code below.
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = label1.Text.Substring(label1.Text.Length - 1) + label1.Text.Remove(label1.Text.Length - 1);
}
private void Form1_Load(object sender, EventArgs e)
{
// The total spaces required to fill the form vary from form.width and the initial label.text.width
// Width | Spaces
// 177 | 13
// 228 | 30
// 297 | 53
// 318 | 60
// The spacesEnd = 60 work for a form with width 319
int spacesBegin = 0, spacesEnd = 60;
label1.Text = "Time:" + System.DateTime.Now.ToString();
label1.AutoSize = false;
label1.Left = -3;
label1.Width = this.Width - 1;
label1.Height = 15;
label1.BorderStyle = BorderStyle.FixedSingle;
for (int i = 0; i < spacesBegin; i++)
label1.Text = " " + label1.Text;
for (int i = 0; i < spacesEnd; i++)
label1.Text += " ";
Timer timer = new Timer();
timer.Tick += timer1_Tick;
timer.Interval = 50;
timer.Start();
}
I am new to C# and Winforms and try to make a moving panel. It should move right until the end of my window and then back left. It should bounce from side to side. But the only thing happened after hours of trying is that it moves left and stops.
Using this form tools:
Timer = tmrMoveBox (interval: 50)
Panel = pnlBox
Label = lblXY (for showing the X and Y coordinates in the form)
Here are my first best try:
private void tmrMoveBox(object sender, EventArgs e)
{
if (pnlBox.Location.X <= 316)
{
for (int i = 0; i <= 316; i++)
{
pnlBox.Location = new Point(
pnlBox.Location.X + 2, pnlBox.Location.Y);
string BoxLocationToString = pnlBox.Location.ToString();
lblXY.Text = BoxLocationToString;
}
}
else if (pnlBox.Location.X >= 0)
{
for (int i = 0; i >= 316; i++)
{
pnlBox.Location = new Point(
pnlBox.Location.X - 2, pnlBox.Location.Y);
string BoxLocationToString = pnlBox.Location.ToString();
lblXY.Text = BoxLocationToString;
}
}
}
And the second best try:
private void tmrMoveBox(object sender, EventArgs e)
{
int runBox = 1;
if(runBox == 1)
{
while (pnlBox.Location.X <= 316)
{
pnlBox.Location = new Point(
pnlBox.Location.X + 2, pnlBox.Location.Y);
string BoxLocationString = pnlBox.Location.ToString();
lblXY.Text = BoxLocationString;
runBox = 0;
}
}
else
{
while(pnlBox.Location.X > 0)
{
pnlBox.Location = new Point(
pnlBox.Location.X - 2, pnlBox.Location.Y);
string BoxLocationString = pnlBox.Location.ToString();
lblXY.Text = BoxLocationString;
runBox = 1;
}
}
}
Tried to use a while loop too but then the panel just disappears.
I'm no expert and just set this moving panel as a goal for myself. Hope anyone can give me a tip.
EDIT:
Form1.Designer.cs
this.timer1.Interval = 50;
this.timer1.Tick += new System.EventHandler(this.tmrMoveBox);
this.timer1.Start();
this.timer1.Step = 2;
Depending on what you're using:
Windows Forms
WPF
Create a Timer and subscribe to the Tick event. Also, you should create new int property Step.
1. Windows Forms:
System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
int Step;
Form1 ()
{
InitializeComponent()
....
t.Interval = 15000; // specify interval time as you want
t.Tick += new EventHandler(timer_Tick);
t.Start();
this.Step = 2;
}
And in ticks event handler put your logic, without while
void timer_Tick(object sender, EventArgs e)
{
if (pnlBox.Location.X >= 316)
{
Step = -2;
}
if (pnlBox.Location.X <= 0)
{
Step = 2;
}
pnlBox.Location = new Point(
pnlBox.Location.X + Step , pnlBox.Location.Y);
string BoxLocationString = pnlBox.Location.ToString();
lblXY.Text = BoxLocationString;
}
So your box will move on one step per one timer tick.
1. WPF:
As System.Windows.Forms.Timer is not available, you may use System.Windows.Threading.DispatcherTimer:
using System.Windows.Threading;
DispatcherTimer t = new DispatcherTimer();
t.Interval = new TimeSpan(0, 0, 15); // hours, minutes, seconds (there are more constructors)
t.Tick += Timer_Tick;
t.Start();
Here is the code I used:
int d= 10;
private void timer1_Tick(object sender, EventArgs e)
{
//Reverse the direction of move after a collision
if(panel1.Left==0 || panel1.Right==this.ClientRectangle.Width)
d = -d;
//Move panel, also prevent it from going beyond the borders event a point.
if(d>0)
panel1.Left = Math.Min(panel1.Left + d, this.ClientRectangle.Width - panel1.Width);
else
panel1.Left = Math.Max(panel1.Left + d, 0);
}
Note:
To check the collision you should check:
Collision with left: panel1.Left==0
Collision with right: panel1.Right==this.ClientRectangle.Width
You should not allow the panel goes beyond the borders even a point, so:
The maximum allowed value for your panel left is this.ClientRectangle.Width - panel1.Width
The minimum allowed value for your panel left is 0
Also It's better to use this.ClientRectangle.Width instead of using hard coded 316.
I have been attempting to understand the tiled listView in c#.net for weeks now with no succession.
I have shrunk my form's height/width (154x154) to the same tile size as the picture(s) (items with pictures) in my listView (which is docked in the form2); when my form2 is shown, you see item[0] in the listView...that is it! (which I want so far, so good!)
I have set the scrollable property to false to do away with both scrollbars (works perfectly fine so far...)
I have hooked both the left and right arrow keys GLOBALLY (which works as it has been thoroughly debugged) and when clicking the RIGHT arrow key, it should VERTICALLY bring up item[1], and so fourth.
The LEFT arrow key would bring up the previous item till it hits 0.
I have tried the following, but it does NOTHING.
private void HotkeyHandler(int i)
{
{
if (this.listView1.InvokeRequired)
{
SetHotkeyCallback p = new SetHotkeyCallback(HotkeyHandler);
this.Invoke(p, new object[] { i });
}
else
{
switch (i)
{
case 1:
listView1.View = View.List;
if (listView1.TopItem.Index > 0)
{
listView1.TopItem = listView1.Items[listView1.TopItem.Index - 1];
}
listView1.View = View.Tile;
break;
case 2:
listView1.View = View.List;
if (listView1.TopItem.Index < listView1.Items.Count)
{
listView1.TopItem = listView1.Items[listView1.TopItem.Index + 1];
}
listView1.View = View.Tile;
break;
}
}
}
}
Please help me, I been loosing my mind for weeks now.
EDIT: The switch within the function above does go off, I have debugged it; therefore, it is not the invoking that is the problem...
I don't think you can do it directly.
The way to get rid of the ScrollBars is indeed to set Scrollable = false;.
But that means what it says: Now the ListView will not scroll.
Here is a common workaround for many scrolling issues:
Place the Listview in a Panel and make it as large as needed to show all Items.
Then in order to scroll simply move the LV up and down:
private void prepare_Click_1(object sender, EventArgs e)
{
// we sit inside a Panel
listView1.Parent = panel1;
// initially they have the same size
listView1.Size = panel1.Size;
listView1.Location = Point.Empty;
// a few test items
for (int i = 0; i < 100; i++)
listView1.Items.Add("Item " + i);
// now grow the height to display all items:
int cols = listView1.Width / listView1.TileSize.Width;
listView1.Height = (listView1.Items.Count / cols) * listView1.TileSize.Height;
}
// moving the LV up looks like scrolling down..
private void scrollDown_Click(object sender, EventArgs e)
{
listView1.Top -= listView1.TileSize.Height;
if (listView1.Bottom < panel1.Height)
listView1.Top = -listView1.Height + panel1.Height;
}
// moving the LV down looks like scrolling up..
private void scrollUp_Click_1(object sender, EventArgs e)
{
listView1.Top += listView1.TileSize.Height;
if (listView1.Top > 0) listView1.Top = 0;
}
I have a panel with 07 buttons that can move them left or right without problems using "drag and drop". My problem is that when I put a button on top of an existing one. I put the button where it already existed 43 button 45 and button 43 is below 45 as shown.
This is my code
private void panelAtalhos_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void panelAtalhos_DragDrop(object sender, DragEventArgs e)
{
//create the button - treeview item selected
Button bt = new Button();
if (createbutton) // createbutton is a global variable
{
bt.Width = 38;
bt.Height = 34;
bt.Top = 2;
bt.Left = panelAtalhos.Controls.Count * (bt.Width);
bt.FlatAppearance.BorderSize = 0;
DateTime data = DateTime.Now;
bt.Text = data.ToString("ss");
bt.FlatStyle = FlatStyle.Flat;
panelAtalhos.Controls.Add(bt);
bt.MouseDown += button_MouseDown;
createbutton = false;
}
else
{
int resto = (int)(System.Windows.Forms.Cursor.Position.X / 38);
((Button)e.Data.GetData(typeof(Button))).Left = resto * 38;
}
}
private void button_MouseDown(object sender, MouseEventArgs e)
{
(sender as Button).DoDragDrop(sender as Button, DragDropEffects.Move);
criarbotao = false;
}
What is missing in the code?
int resto = (int)(System.Windows.Forms.Cursor.Position.X / 38);
You have two problems. One is the Z-order, the other is this statement. It is not correct, you must map the absolute cursor position to the relative position for the button. Relative from the client area of its parent, the panel. Right now you're sending it off into the weeds, too far to the right. Easily far enough that it won't be visible anymore. Code ought to resemble:
var btn = (Button)e.Data.GetData(typeof(Button));
var pos = btn.Parent.PointToClient(Cursor.Position);
btn.Left = (pos.X / 38) * 38;
btn.BringToFront();
i have taken one Flow layout panel and placed multiple picture box inside in it. now i want when i will place my mouse at the right or left most edge of the Flow layout panel then rest of picture will scroll out. just think about windows 8 start screen where many tiles appear in screen and when we place mouse at right most edge on the screen then rest of the tiles scroll out. i want to simulate same thing in windows form with Flow layout panel.
i want my Flow layout panel will not show scroll bar but images will scroll out when i will place mouse right or left most part on the panel. here is my screen shot
some one told me to do it this way...here is bit code
Set AutoScrollPosition property in MouseMove event of Panel.
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
panel1.AutoScrollPosition = new Point(e.X, e.Y);
}
but this trick was not good. AutoScrollPosition works when scroll bar is visible but in my case i do not want to show scroll bar with Flow layout panel. i want smooth scrolling images from left to right or right to left. anyone can help me to achieve what i am trying to do....if possible guide me with respect of coding. thanks
EDIT
Here i am giving my full code after modification following #Taw suggestion but it is not working fine....rather flickering found when picture move. anyway here is the full code.
namespace ScrollTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
flowLayoutPanel1.MouseMove += MouseScroll;
foreach (Control x in this.Controls)
{
if (x is PictureBox)
{
((PictureBox)x).MouseMove += MouseScroll;
}
}
}
int near = 33;
private void MouseScroll(object sender, MouseEventArgs e)
{
Point mouse = flowLayoutPanel1.PointToClient(MousePosition);
Rectangle C = flowLayoutPanel1.ClientRectangle;
int dLeft = mouse.X - C.Left;
int dTop = mouse.Y - C.Top;
int dRight = C.Right - mouse.X;
int dBottom = C.Bottom - mouse.Y;
int dX = dLeft < near ? dLeft : dRight < near ? -dRight : 0;
int dY = dTop < near ? dTop : dBottom < near ? -dBottom : 0;
if (dX != 0 | dY != 0) scrollFLP(dX, dY);
}
void scrollFLP(int deltaX, int deltaY)
{
flowLayoutPanel1.Left += getSpeedFromDistance(deltaX);
flowLayoutPanel1.Top += getSpeedFromDistance(deltaY);
System.Threading.Thread.Sleep(11);
}
int getSpeedFromDistance(int delta)
{
int sig = Math.Sign(delta);
int d = Math.Abs(delta);
if (d > near / 2) return sig;
else if (d > near / 3) return near / 10 * sig;
else if (d > near / 4) return near / 8 * sig;
else if (d > near / 5) return near / 5 * sig;
else return near * sig;
}
}
}
basically i am trying achieve something like suppose i have flow layout panel and which has many picture box inside it with many images as the screen shot but scroll bar should not show rather scroll will happen automatically when i will place my mouse at the top or bottom of the flow layout panel like carousel.
see this picture of your application
when place my mouse at the right end then it scroll and form background shown which i do not want. i want picture box will scroll & scroll upto last one not more than that.
any idea how to do it. thanks
2nd Edit
this code i added as per your suggestion
public Form1()
{
InitializeComponent();
for (int i = 0; i < 666; i++)
{
PictureBox pan = new PictureBox();
//pan.MouseMove += MouseScroll;
//pan.MouseLeave += outSideCheck;
pan.Size = new Size(75, 75);
pan.BackColor = Color.FromArgb(255, (i * 2) & 255, (i * 7) & 255, (i * 4) & 255);
flowLayoutPanel1.Controls.Add(pan);
}
//flowLayoutPanel1.MouseMove += MouseScroll;
//this.flowLayoutPanel1.MouseLeave += outSideCheck;
mouseScroller MSC = new mouseScroller();
MSC.registerControl(flowLayoutPanel1); // FLP = your FlowLayouPanel
MSC.timerSpeed = 5; // optional
MSC.nearness = 100; // optional
flowLayoutPanel1.AutoScroll = false;
}
now the apps doing wired behavior after adding new code. if i am making any mistake then guide me please. thanks
This is a two-part problem:
How to grab the event
How to scroll a FlowLayoutPanel with its scrollbars invisible.
Second first. It is not an easy task from what I found, unless you use a simple and rather common trick: Don't actually scroll it! Instead place it into a Panel and then control its position inside that Panel.
To do this you add a Panel panel1 to your Form, Dock or Anchor it as you need to and set its Autoscroll = false (!) (Which is not the way it is usually done, when you want to make, say a PictureBox scrollable. But we don't want the Panel to show it Scrollbars either.)
Set the FLP to its desired size and place it into the Panel, it obviously also has Autoscroll = false, and we're ready to tackle the other problem of setting up the event..:
First you add the MouseScroll event below to your code and then you hook every control up to it you want to work with the mouse move, namely the FLP:
flowLayoutPanel1.MouseMove += MouseScroll;
..and also each of your PictureBoxes, maybe like this
// your creation loop..
PictureBox pbox = new PictureBox();
pbox.MouseMove += MouseScroll; // <<--- hook into to the mousemove
pan.MouseLeave += outSideCheck; // <<--- hook into to the mouseleave
// .. do your stuff.. here I put some paint on to test..
pbox.BackColor = Color.FromArgb(255, 111, (i * 3) & 255, (i * 4) & 255);
flowLayoutPanel1.Controls.Add(pbox);
or however you create them..
Edit 2 I have changed my original code once more. It now includes an outside check, a check for moving towards the closest edge and a workaround for tha mousemove bug. It uses a Timer set to maybe 30ms. The speed mapping is in a function of its own.
flowLayoutPanel1.MouseMove += MouseScroll;
this.flowLayoutPanel1.MouseLeave += outSideCheck;
flowLayoutPanel1.AutoScroll = false;
int near = 33;
Point lastLocation = Point.Empty;
int dX = 0;
int dY = 0;
private void MouseScroll(object sender, MouseEventArgs e)
{
Point mouse = panel1.PointToClient(MousePosition);
Rectangle C = panel1.ClientRectangle;
// mouseMove has a bug, we need to workaround
if (mouse == lastLocation) return;
if (lastLocation == Point.Empty) { lastLocation = mouse; return; }
// distance from each edge
int dLeft = mouse.X - C.Left;
int dTop = mouse.Y - C.Top;
int dRight = C.Right - mouse.X;
int dBottom = C.Bottom - mouse.Y;
// relevant distances with sign
dX = dLeft < near ? dLeft : dRight < near ? -dRight : 0;
dY = dTop < near ? dTop : dBottom < near ? -dBottom : 0;
// we need the closest edge to check if we are moving in or out
List<int> edges = new List<int>() { dLeft, dTop, dRight, dBottom };
var closest = edges.IndexOf(edges.Min());
// if we are moving
if (dX != 0 | dY != 0)
// if moving out: go else stop going
if (!movingIn(mouse, closest)) timer1.Start(); else timer1.Stop();
// remember position
lastLocation = mouse;
}
bool movingIn(Point current, int Edge)
{
switch (Edge)
{
case 0: return current.X > lastLocation.X;
case 1: return current.Y > lastLocation.Y;
case 2: return current.X < lastLocation.X;
case 3: return current.Y < lastLocation.Y;
}
return false;
}
void scrollFLP(int deltaX, int deltaY)
{
flowLayoutPanel1.Left += getSpeedFromDistance(deltaX);
flowLayoutPanel1.Top += getSpeedFromDistance(deltaY);
Size C = panel1.ClientSize;
if (flowLayoutPanel1.Left > 1) { flowLayoutPanel1.Left = 0; timer1.Stop(); }
if (flowLayoutPanel1.Right < C.Width)
{ flowLayoutPanel1.Left = C.Width - flowLayoutPanel1.Width; timer1.Stop(); }
if (flowLayoutPanel1.Top > 1) { flowLayoutPanel1.Top = 0; timer1.Stop(); }
if (flowLayoutPanel1.Bottom < C.Height)
{ flowLayoutPanel1.Top = C.Height - flowLayoutPanel1.Height; timer1.Stop(); }
}
int getSpeedFromDistance(int delta)
{
int sig = Math.Sign(delta);
int d = Math.Abs(delta);
if (d > near / 2) return sig;
else if (d > near / 3) return 2 * sig;
else if (d > near / 4) return 4 * sig;
else if (d > near / 5) return 6 * sig;
else return 10 * sig;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (insidePanel()) scrollFLP(dX, dY); else timer1.Stop();
}
bool insidePanel()
{
return panel1.ClientRectangle.Contains(panel1.PointToClient(MousePosition));
}
private void outSideCheck(object sender, EventArgs e)
{
if (!insidePanel()) {timer1.Stop(); lastLocation = Point.Empty;}
}
Of course you'll want to play with the various 'magic' numbers :-)
Stop code and direction check are now included.
As usual, key is to know precisely what you want.. I hope this gets you started on ways to achieve it!
It's been a while since this question was asked. I just encountered the problem. My scenario was a little different, but I still think it's a solution to the same problem (at worst a timer control can be used because autoscroll is not turned on).
Here is my scenario: I have one panel control (normal panel). I have an PictureBox in it that I made with zoom. I'm making rectangular selections on top of this image, and when the selections spilled out of the panel, my panel was supposed to slide in the direction I was selecting. (in my scenario, mouse is pressed)(also in my scenario, autoscroll is on). This is how I solved it without writing so much code:
I added two private variable for scroll position (Valid for the whole class scope).
private int xPos;
private int yPos;
private int speed = 5;
and I assigned them the current scroll positions when the form is loaded.
private void Form1_Load(object sender, EventArgs e)
{
//when I change the scrollbar manually or change with zoom I still
//need to add these lines to the related event
xPos = panel1.HorizontalScroll.Value;
yPos = panel1.VerticalScroll.Value;
}
and inside my picturebox's mousemove event
private void picturebox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) {
Point mouse = panel1.PointToClient(MousePosition);
if (!panel1.ClientRectangle.Contains( mouse ))
{
Rectangle CRect = panel1.ClientRectangle;
int dLeft = mouse.X - CRect.Left;
int dRight = CRect.Right - mouse.X;
int dTop = mouse.Y - CRect.Top;
int dBottom = CRect.Bottom - mouse.Y;
if(dLeft < 0 && panel1.HorizontalScroll.Value > 0)
{
xPos = -panel1.AutoScrollPosition.X - speed;
}
if (dRight < 0 && panel1.HorizontalScroll.Value < panel1.HorizontalScroll.Maximum)
{
xPos = -panel1.AutoScrollPosition.X + speed;
}
if (dTop < 0 && panel1.VerticalScroll.Value > 0)
{
yPos = -panel1.AutoScrollPosition.Y - speed;
}
if (dBottom < 0 && panel1.VerticalScroll.Value < panel1.VerticalScroll.Maximum)
{
yPos = -panel1.AutoScrollPosition.Y + speed;
}
panel1.AutoScrollPosition = new Point(xPos, yPos);
}
}
}