How to scroll listview items programmatically - c#

I have a listview control on my WinForms application.
here, on click of separate button, i do change couple of listview items backcolor and reload the whole grid as there are certain changes into database so, reloading from database on each click of button.
Now, problem is, once the grid is reloaded then lastly added items are scrolled so, need to scroll all items and find so, it makes hard to end user.
Is there any way to ,scroll the lastly added items or updated items into listview automatically (I mean, programmatically so, it could be view to user directly without being manually scrolled).

listView1.EnsureVisible(X);
where X is the item index.
This snippet can be used to scroll the ListView automatically to a particular index in the listView.
Consider the code: with this you can automatically scroll to the index 8 on button click
private void button2_Click(object sender, EventArgs e)
{
listView1.EnsureVisible(8);
}

Despite #user3711357 correct answer, I spent too much time trying to understand why it is not working for me.
I found that trying to call EnsureVisible in the constructor of the form will not work.
public class MyForm
{
public MyForm()
{
InitializeComponent();
listView1.EnsureVisible(8); // will not work !!!
}
private void MyForm_Load(object sender, EventArgs e)
{
listView1.EnsureVisible(8); // Works fine
}
}

Before you refresh the list, store the currently focussed or selected item (depending on how your interaction code works) into a variable, then you can restore the selected item afterwards. For example;
Dim selectedObjectName = listview.SelectedItems(0).Name
...
' refresh your list
...
Dim vItem as ListViewItem
If listview.SelectedItem.ContainsKey(selectedObjectName) Then
vItem = listview.Items(selectedObjectName)
Else
vItem = listview.Items(0)
End If
vItem.Selected = True
vItem.Focus

Can send messages directly.
public partial class Form1 : Form
{
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
public Form1()
{
InitializeComponent();
c_scroll.ScrollSlide += C_scroll_ScrollSlide;
}
private void C_vScrollBar_Scroll(object sender, ScrollEventArgs e)
{
const int LVM_SCROLL = (0x1000 + 20);
SendMessage(c_listView_show.Handle, LVM_SCROLL, 0, e.NewValue - e.OldValue);
}
}

Related

Opening a dateTimePicker using a PictureBox

Is there any way to open a dateTimePicker using a PictureBox in c# windowsform?
I wanted to minimize the dateTimePicker size so it can only show the drop down arrow and the calendar picture but thats not possible, so now i want to open the calendar using a PictureBox, is that possible?
Thanks
Although it is not possible to programatically show picker in DateTimePicker, you can create your own this way:
[ToolboxItem(true)]
public class CustomDateTimePicker : DateTimePicker
{
private const int WM_KEYDOWN = 0x100;
private const int VK_F4 = 0x73;
private const int F4_KEYDOWN_LPARAM = 0x003e0001;
public void ShowPicker()
{
Focus();
var m = Message.Create(Handle, WM_KEYDOWN, new IntPtr(VK_F4), new IntPtr(F4_KEYDOWN_LPARAM));
WndProc(ref m);
}
}
Than in Click handler of your picture box just call that ShowPicker method.
private void PictureBox1_Click(object sender, EventArgs e)
{
customDateTimePicker1.ShowPicker();
}

How do I display another UserControl by Clicking on button in One UserControl?

I'm very new to coding and at this moment I've started a personal project with Windows Form Application.
I have a form with a few buttons and a panel as a container. The buttons load the usercontrol as expected with the help of this link: https://www.youtube.com/watch?v=wZ63E_9ASwM
But, in One of the usercontrol I've got 2 buttons. That I want to load usercontrols for each button. I have no idea how to go about to make this work. I have tried using the same method for this as the above without succes.
I found another Question that is asking the exact same thing, but it doesn't make any sense to me. Dynamically loading UserControl after clicking button on another UserControl
I have a concern about the 2 buttons in the usercontrol. If a usercontrol is loaded in to the panelcontainer, will the buttons then disappear
Can someone explains this or is there a easier way to make this work?
This is the button that loads a Usercontrol with 2 buttons in form1(cs).
private void Personbutton_Click(object sender, EventArgs e)
{
panelSelection.Height = Personbutton.Height;
panelSelection.Top = Personbutton.Top;
if (!ContainerPanel.Controls.Contains(ucPerson.Instance))
{
ContainerPanel.Controls.Add(ucPerson.Instance);
ucPerson.Instance.Dock = DockStyle.Fill;
ucPerson.Instance.BringToFront();
}
else
ucPerson.Instance.BringToFront();
}
This is the usercontrol that loads in to the container.
private static ucPerson _instance;
public static ucPerson Instance
{
get
{
if (_instance == null)
_instance = new ucPerson();
return _instance;
}
}
When pressing these buttons I want to load another/new usercontrol. Without making the buttons disappear.
private void CPbutton_Click(object sender, EventArgs e)
{
CPbutton.FlatAppearance.BorderSize = 1;
APbutton.FlatAppearance.BorderSize = 0;
}
private void APbutton_Click(object sender, EventArgs e)
{
APbutton.FlatAppearance.BorderSize = 1;
CPbutton.FlatAppearance.BorderSize = 0;
}

Showing starting text of Mulitline TextBox when focus is changed

I am creating a form which has a Multiline TextBox to enter an URL. Expected URLs will be very long.
User will paste the URL and move to next box.
Right now, TextBox shows ending part of the URL when user moves to next TextBox. I want such that it will show starting of URL (Domain name) instead of trailing part.
Current:
Expected:
And this should happen when user leaves the TextBox.
I tried various methods of Selection in textBox_Leave() event but I guess, these methods won't work if focus is lost.
I am using .Net framework 3.5.
Update: Textbox I am using is Multiline. Answers suggested by #S.Akbari and #Szer are perfect if the Mutliline property is set to False. I realized it late that Multiline will play such a significant role. Hence updating the question!
Use SelectionStart in the Leave event should works:
private void textBox1_Leave(object sender, EventArgs e)
{
textBox1.SelectionStart = 0;
}
Before:
After leaving TextBox:
Tried it and it works. Proof
public Form1()
{
InitializeComponent();
textBox1.LostFocus += TextBox1_LostFocus;
}
private void TextBox1_LostFocus(object sender, EventArgs e)
{
textBox1.SelectionStart = 0;
textBox1.SelectionLength = 0;
}
I can see how it doesn't work with the Multiline property set to true.
A simple API call can make this work:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
private const int WM_VSCROLL = 0x115;
private const int SB_TOP = 6;
void textBox1_Leave(object sender, EventArgs e) {
SendMessage(textBox1.Handle, WM_VSCROLL, (IntPtr)SB_TOP, IntPtr.Zero);
}

Adding scroll bar to windows forms, c#

I need to add scroll horizontal and vertical scroll bar. The problem is that they doesn't work, as in when I use them the screen doesn't move.
VScrollBar vScrollBar1 = new VScrollBar();
HScrollBar hScrollBar1 = new HScrollBar();
vScrollBar1.Dock = DockStyle.Left;
hScrollBar1.Dock = DockStyle.Bottom;
Controls.Add(vScrollBar1);
Controls.Add(hScrollBar1);
I use the code to add scroll bars, how do I activate them or get them to work as I need?
Thanks!
You usually don't add Scrollbars; you set AutoScroll = true in the form's property panel.
Now when any control grows out of the Form or is moved over right or bottom border the Form will show the necessary Scrollbar.
You can test it with a Label and a TextBox: Set the Label to the right border and script the TextBox's TextChanged event like this:
private void textBox1_TextChanged(object sender, EventArgs e)
{
label1.Text = textBox1.Text;
}
Now run the programm and enter stuff into the Textbox; you will observe how the Label grows and how the Form brings up a horizontal Scrollbar when it goes over the edge.
Note 1: This will not work if the Form has AutoSize = true - then instead the form will grow! If the Form has both AutoSize and AutoScroll true, then AutoSize will win.
Note 2: This test will only work if the Label has AutoSize = true, as it has by default..
You need to use the Panel control as container of your child controls and set "AutoScroll" property to true.
Set true to AutoScroll property of Form.
Write this code in your Form Load Event, and you will get your scroll bar, like I am writing it here in my Form Load Event.
private void Form1_Load(object sender, EventArgs e)
{
Panel my_panel = new Panel();
VScrollBar vScroller = new VScrollBar();
vScroller.Dock = DockStyle.Right;
vScroller.Width = 30;
vScroller.Height = 200;
vScroller.Name = "VScrollBar1";
my_panel.Controls.Add(vScroller);
}
vScrollbars and hScrollbars are just plain controls without code. [UI]
You need to code to make them do something!
Or just set the property 'AutoScroll = true;' in your form or add a panel and set it to true.
However your control needs Focus() to scroll with your mouse wheel.
Here is a little workaround:
public Main()
{
InitializeComponent();
//Works for panels, richtextboxes, 3rd party etc..
Application.AddMessageFilter(new ScrollableControls(panel1, richtextbox1, radScrollablePanel1.PanelContainer));
}
ScrollableControls.cs:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
//Let controls scroll without Focus();
namespace YOURNAMESPACE
{
internal struct ScrollableControls : IMessageFilter
{
private const int WmMousewheel = 0x020A;
private readonly Control[] _controls;
public ScrollableControls(params Control[] controls)
{
_controls = controls;
}
bool IMessageFilter.PreFilterMessage(ref Message m)
{
if (m.Msg != WmMousewheel) return false;
foreach (var item in _controls)
{
ScrollControl(item, ref m);
}
return false;
}
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
private static void ScrollControl(Control control, ref Message m)
{
if (control.RectangleToScreen(control.ClientRectangle).Contains(Cursor.Position) && control.Visible)
{
SendMessage(control.Handle, m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32());
}
}
}
}

value wont change in an event

I've create a list of canvases in wpf, and I have a button click event. I want that when I press the button it will add to the list new canvas. but when I try to change the property of the canvas in another window, it says the index was out of bounds, which means the list didnt add the canvas. I've created a method to check that and indeed it says the index is 0.
I've this with an array also, same here, I change its value but its still wrote the value is 0. this is the code:
public partial class New_Paint : Window
{
public List<Canvas> paintsList = new List<Canvas>();
public Canvas painting = new Canvas();
private void ok_MouseUp(object sender, MouseButtonEventArgs e)
{
paintsList.Add(painting);
this.Close();
}
}
and this is the moethod to check its size:
public int getSize()
{
return paintsList.Count;
}
and here is the code in the main window:
private void button1_Click(object sender, RoutedEventArgs e)
{
textBox1.Text = paint.getSize() + "";
}
the methos return 0 although i click "ok". the list just wont add the items.
I take it you're new at this? Your list of canvases belong to your instance of New_Paint, and you only add one canvas to that list before closing the window (at least in the code you've shown). I don't see why you would expect more than one. You need to have a master list of canvases that is owned by whatever is managing your child windows.

Categories