Similar to this question:
get contextmenustrip from toolstripmenuitem
Except that now I need to find the object whose context menu was opened when the ToolStripMenuItem was clicked.
SourceControl, Parent, Owner, and GetParentControl() all return null.
Initially I had a TreeView, and it's ContextMenuStrip property was set.
Here's my preliminary code:
ToolStripMenuItem tsmi = (ToolStripMenuItem)sender;
ToolStripMenuItem tsmip = (ToolStripMenuItem)tsmi.OwnerItem;
ContextMenuStrip cms = (ContextMenuStrip)tsmip.GetCurrentParent();
TreeView tv = (TreeView)cms.SourceControl;
// returns null, but not in the cms_openHandler
tv.Nodes.Add(new TreeNode("event fired."));
Am I getting the ContextMenuStrip improperly? Why is it that the SourceControl property of the cms works in the OpenHandler, but not from the ToolStripMenuItem eventhandler?
Form1.Designer.cs:
namespace TestWFA
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.treeView1 = new System.Windows.Forms.TreeView();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.expandToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.childrenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.allDescendantsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.collapseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.childrenToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.parentToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.childrenToolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
this.allDescendantsToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.contextMenuStrip1.SuspendLayout();
this.SuspendLayout();
//
// treeView1
//
this.treeView1.ContextMenuStrip = this.contextMenuStrip1;
this.treeView1.Location = new System.Drawing.Point(64, 75);
this.treeView1.Name = "treeView1";
this.treeView1.Size = new System.Drawing.Size(262, 247);
this.treeView1.TabIndex = 0;
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.expandToolStripMenuItem,
this.collapseToolStripMenuItem});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(153, 70);
this.contextMenuStrip1.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip1_Opening);
//
// expandToolStripMenuItem
//
this.expandToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.childrenToolStripMenuItem,
this.allDescendantsToolStripMenuItem});
this.expandToolStripMenuItem.Name = "expandToolStripMenuItem";
this.expandToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.expandToolStripMenuItem.Text = "Expand";
//
// childrenToolStripMenuItem
//
this.childrenToolStripMenuItem.Name = "childrenToolStripMenuItem";
this.childrenToolStripMenuItem.Size = new System.Drawing.Size(161, 22);
this.childrenToolStripMenuItem.Text = "Children";
this.childrenToolStripMenuItem.Click += new System.EventHandler(this.childrenToolStripMenuItem_Click);
//
// allDescendantsToolStripMenuItem
//
this.allDescendantsToolStripMenuItem.Name = "allDescendantsToolStripMenuItem";
this.allDescendantsToolStripMenuItem.Size = new System.Drawing.Size(161, 22);
this.allDescendantsToolStripMenuItem.Text = "All Descendants";
this.allDescendantsToolStripMenuItem.Click += new System.EventHandler(this.allDescendantsToolStripMenuItem_Click);
//
// collapseToolStripMenuItem
//
this.collapseToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.childrenToolStripMenuItem1,
this.parentToolStripMenuItem,
this.childrenToolStripMenuItem2,
this.allDescendantsToolStripMenuItem1});
this.collapseToolStripMenuItem.Name = "collapseToolStripMenuItem";
this.collapseToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.collapseToolStripMenuItem.Text = "Collapse";
//
// childrenToolStripMenuItem1
//
this.childrenToolStripMenuItem1.Name = "childrenToolStripMenuItem1";
this.childrenToolStripMenuItem1.Size = new System.Drawing.Size(161, 22);
this.childrenToolStripMenuItem1.Text = "All Ancestors";
this.childrenToolStripMenuItem1.Click += new System.EventHandler(this.childrenToolStripMenuItem1_Click);
//
// parentToolStripMenuItem
//
this.parentToolStripMenuItem.Name = "parentToolStripMenuItem";
this.parentToolStripMenuItem.Size = new System.Drawing.Size(161, 22);
this.parentToolStripMenuItem.Text = "Parent";
this.parentToolStripMenuItem.Click += new System.EventHandler(this.parentToolStripMenuItem_Click);
//
// childrenToolStripMenuItem2
//
this.childrenToolStripMenuItem2.Name = "childrenToolStripMenuItem2";
this.childrenToolStripMenuItem2.Size = new System.Drawing.Size(161, 22);
this.childrenToolStripMenuItem2.Text = "Children";
this.childrenToolStripMenuItem2.Click += new System.EventHandler(this.childrenToolStripMenuItem2_Click);
//
// allDescendantsToolStripMenuItem1
//
this.allDescendantsToolStripMenuItem1.Name = "allDescendantsToolStripMenuItem1";
this.allDescendantsToolStripMenuItem1.Size = new System.Drawing.Size(161, 22);
this.allDescendantsToolStripMenuItem1.Text = "All Descendants";
this.allDescendantsToolStripMenuItem1.Click += new System.EventHandler(this.allDescendantsToolStripMenuItem1_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(406, 365);
this.Controls.Add(this.treeView1);
this.Name = "Form1";
this.Text = "Form1";
this.contextMenuStrip1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TreeView treeView1;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem expandToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem childrenToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem allDescendantsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem collapseToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem childrenToolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem parentToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem childrenToolStripMenuItem2;
private System.Windows.Forms.ToolStripMenuItem allDescendantsToolStripMenuItem1;
}
}
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TestWFA
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
treeView1.Nodes.Add(new TreeNode("root"));
}
private void childrenToolStripMenuItem1_Click(object sender, EventArgs e)
{
TreeView tv = GetSourceControl(sender) as TreeView;
if (tv != null)
{
tv.Nodes.Add("Tree event catched!");
}
/*ToolStripMenuItem tsmi = (ToolStripMenuItem)sender;
ToolStripMenuItem tsmip = (ToolStripMenuItem)tsmi.OwnerItem;
ContextMenuStrip cms = (ContextMenuStrip)tsmip.GetCurrentParent();
ToolStrip ts = tsmip.GetCurrentParent();
IContainer c = cms.Container;
TreeView tv = (TreeView)c;
tv.Nodes.Add(new TreeNode("event fired."));*/
}
private object GetSourceControl(object Sender)
{
if (Sender as ContextMenuStrip != null)
{
return ContextMenuStrip.SourceControl;
}
var item = Sender as ToolStripItem;
// move to root item
while (item.OwnerItem != null)
{
item = item.OwnerItem;
}
// we have root item now, so lets take ContextMenuStrip object
var menuObject = item.Owner as ContextMenuStrip;
if (menuObject != null)
{
return menuObject.SourceControl;
}
return null;
}
private void parentToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void childrenToolStripMenuItem2_Click(object sender, EventArgs e)
{
}
private void allDescendantsToolStripMenuItem1_Click(object sender, EventArgs e)
{
}
private void childrenToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void allDescendantsToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
try
{
ContextMenuStrip cms = (ContextMenuStrip)sender;
}
catch
{
}
try
{
TreeView tv = (TreeView)sender;
}
catch
{
}
}
}
}
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace TestWFA
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Unfortunately I don't know of any way to upload the files. I tried uploading them as imgs, that didn't work.
Suppose you have ContextMenuStrip setted to TreeView. You can easily get control for which menu was triggered from Opened handler for your ContextMenuStrip:
private void contextMenuStrip1_Opened(object sender, EventArgs e)
{
TreeView tv = (sender as ContextMenuStrip).SourceControl as TreeView;
tv.Nodes.Add("Tree event catched!");
}
This code would also work if ContextMenuStrip was set to treeView's item.
PS: In real app you shouldn't use construction like (sender as ContextMenuStrip).SourceControl as TreeView; because of possibility of null pointer. You should check for null after each cast instead.
[EDIT]
OK, now I understand your aim.
When you handle menu item sender object points to item triggered event. And to find out the control for which context menu was popped up you should do three things:
Find root item. Its likely, that clicked item is subitem for another item or deeper.
From root item you should find out ContextMenuStrip object
It's easy to find out interesting control from ContextMenuStrip's SourceControl property
I wrote simple method to do all that job:
/// <summary>
/// Gets controls for context menu
/// </summary>
/// <param name="Sender">Sender object from menu event handler</param>
/// <returns></returns>
private object GetSourceControl(Object Sender)
{
// ContextMenuStrip sended?
if (Sender as ContextMenuStrip != null)
{
ContextMenuStrip cms = Sender as ContextMenuStrip;
return cms.SourceControl;
}
var item = Sender as ToolStripItem;
// move to root item
while (item.OwnerItem != null)
{
item = item.OwnerItem;
}
// we have root item now, so lets take ContextMenuStrip object
var menuObject = item.Owner as ContextMenuStrip;
if (menuObject != null)
{
return menuObject.SourceControl;
}
return null;
}
You can simply use it. For example we have menu item click event handler:
private void toolStripMenuItem1_Click(object sender, EventArgs e)
{
TreeView tv = GetSourceControl(sender) as TreeView;
if (tv != null)
{
tv.Nodes.Add("Tree event catched!");
}
}
[EDIT2]
As turned out this problem was discused early ( SourceControl of ContextMenuStrip is Nothing in ToolStripMenuItem Click? ). SourceControl property is not null when you are click on root item, but in case you click subitem it equals null. So the solution is to store SourceControl's value somwhere to use later. I suggest to do this in Tag property. So all methods would be looks like:
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
contextMenuStrip1.Tag = (sender as ContextMenuStrip).SourceControl;
}
....
private object GetSourceControl(object Sender)
{
if (Sender as ContextMenuStrip != null)
{
return ContextMenuStrip.SourceControl;
}
var item = Sender as ToolStripItem;
// move to root item
while (item.OwnerItem != null)
{
item = item.OwnerItem;
}
// we have root item now, so lets take ContextMenuStrip object
var menuObject = item.Owner as ContextMenuStrip;
if (menuObject != null)
{
return menuObject.Tag;
}
return null;
}
In the linked question there is workaround with private field, but Tag property is habitual for me
Related
I am trying to modify (add or remove) items of a combobox while the form is already running, I tried the methode add this.comboBox1.Items.add("test2"); but it only add the item if it runs before Application.Run(form); .
Why it is not updating/adding the item in the combobox ?
Form1.designer.cs:
namespace WindowsFormsApp1
{
partial class Form1
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// comboBox1
//
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Items.AddRange(new object[] {
"test"});
this.comboBox1.Location = new System.Drawing.Point(422, 116);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(121, 24);
this.comboBox1.TabIndex = 0;
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.comboBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
public void test() {
this.comboBox1.Items.add("test2");
}
#endregion
private System.Windows.Forms.ComboBox comboBox1;
}
}
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 form = new Form1();
Application.Run(form);
form.test();
}
}
}
EDIT
How to achieve a periodical update of items by a function?
Instead of using SelectIndexChanged, you should use the click event
In this example I use a button to add an combobox item eveytime I click on it
might not be the best approach but it works fine
List<string> itemList = new List<string>();
int i=0;
private void button1_Click(object sender, EventArgs e)
{
i++;
itemList.Add("Test N° "+i);
}
private void comboBox1_Click(object sender, EventArgs e)
{
comboBox1.Items.Clear();
foreach(string item in itemList)
{
comboBox1.Items.Add(item);
}
}
And your programm isn't well made, Form1.cs.designer is use to create the UI (User Interface) of your programm, you MUST NOT add your function here.
FormX.cs.designer = UI, design
FormX.cs = functions
Programm.cs = defined which FormX.cs will run first (new(Form1))
You can also use it to add item with a function
Example :
public Form1()
{
InitializeComponent();
AddTenItems();
}
List<string> itemList = new List<string>();
int i=0;
private void button1_Click(object sender, EventArgs e)
{
itemList.Add("Test N° "+i);
i++;
}
private void AddTenItems()
{
for(int i=0; i<10; i++)
{
itemList.Add("Added N°" + i);
}
}
private void comboBox1_Click(object sender, EventArgs e)
{
comboBox1.Items.Clear();
foreach(string item in itemList)
{
comboBox1.Items.Add(item);
}
}
I have found a very helpful feature which is timers.
I have used a timer initialized inside the form constructor in order to update periodically the combobox, in the following example it added an item which is current time to the dropbox every 2 seconds for 5 times:
Form1.Designer.cs:
namespace WindowsFormsApp1
{
partial class Form1
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.timer1 = new System.Windows.Forms.Timer();
this.SuspendLayout();
//
// comboBox1
//
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Items.AddRange(new object[] {
"test"});
this.comboBox1.Location = new System.Drawing.Point(422, 116);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(121, 24);
this.comboBox1.TabIndex = 0;
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.comboBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.Timer timer1;
}
}
Form1.cs
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InitializeTimer();
}
private void InitializeTimer()
{
counter = 0;
timer1.Interval = 2000;
timer1.Enabled = true;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
}
private void timer1_Tick(object sender, System.EventArgs e)
{
if (counter >= 5)
{
// Exit loop code.
timer1.Enabled = false;
counter = 0;
}
else
{
// Run your procedure here.
// Increment counter.
counter = counter + 1;
this.comboBox1.Items.Add(DateTime.Now.ToString("h:mm:ss tt"));
}
}
I have two windows forms in my application. First one is Main form and the second one is lookup form. I'm trying to open lookup form from the main form in a text box key leave event and then I'm opening the lookup form. My lookup form has a data grid view and I' loading it in the form load event of the lookup form. I'm reading my selected value on the grid view of the lookup window to an object. I want to close the lookup window as soon as I read the values of the selected row to the object and I want to pass it to the main form? How can I do that?
This is what I have done.
In the main form.
LookupModelType="";
if (e.KeyCode.Equals(Keys.F3))
{
foreach (Form frm in Application.OpenForms)
{
if (frm is FormControllers.Lookup)
{
if (frm.WindowState == FormWindowState.Minimized)
{
frm.WindowState = FormWindowState.Normal;
frm.Focus();
return;
}
}
}
LookupModelType = "Product";
FormControllers.Lookup newLookUp = new FormControllers.Lookup(LookupModelType);
newLookUp.ShowDialog(this);
}
In the lookup window
private string GridType = "";
public Lookup(String LookupModelType)
{
InitializeComponent();
this.GridType = LookupModelType;
}
private void Lookup_Load(object sender, EventArgs e)
{
if (GridType == "Product")
{
using(DataControllers.RIT_Allocation_Entities RAEntity = new DataControllers.RIT_Allocation_Entities())
{
dgvLookup.DataSource = RAEntity.TBLM_PRODUCT.ToList<DataControllers.TBLM_PRODUCT>();
}
}
dgvLookup.ReadOnly = true;
}
private void dgvLookup_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0)
{
return;
}
int index = e.RowIndex;
dgvLookup.Rows[index].Selected = true;
}
you can do it like blow :
in the Main form :
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F3)
{
LookupForm look = new LookupForm();
var result = look.ShowDialog();
if(result == DialogResult.OK)
{
MessageBox.Show(look.data.ToString());
}
}
}
and in the look up form you have to declare 1 variable and fill whenever cell clicked
public partial class LookupForm : Form
{
public object data = new object();
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
data = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
this.DialogResult = DialogResult.OK;
this.Close();
}
}
of course, for better performance, you can declare the variable in specific type
To share data between Parent Child forms using events, here are the things needed:
A public custom event args class to share data.
Child form to have a event.
In your parent form whenever you create an instance of child, you
need to register eventhandlers
Please note that the code below is just a demo code and you will need to add null checks etc. to make it "robust".
Custom event args below
public class ValueSelectedEventArgs : EventArgs
{
public object Value { get; set; }
}
Your lookup form should have the following event declared:
public event EventHandler ValueSelected;
protected virtual void OnValueSelected(ValueSelectedEventArgs e)
{
EventHandler handler = ValueSelected;
if (handler != null)
{
handler(this, e);
}
// if you are using recent version of c# you can simplyfy the code to ValueSelected?.Invoke(this, e);
}
In my case I am firing the event on listbox selected index change and closing the form as well. Code for it:
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var i = this.checkedListBox1.SelectedIndex;
ValueSelectedEventArgs args = new ValueSelectedEventArgs();
args.Value = i;
OnValueSelected(args);
this.Close();
}
Finally in the parent form you have to register for the eventhandler
private void textBox1_Leave(object sender, EventArgs e)
{
lookup myLookup = new lookup();
myLookup.ValueSelected += MyLookup_ValueSelected;
myLookup.Show();
}
private void MyLookup_ValueSelected(object sender, EventArgs e)
{
textBox2.Text = (e as ValueSelectedEventArgs).Value.ToString();
}
I personal like to add dynamically the lookup window, and I do something like this:
//examble object
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
// the value which you want to get from datagridview
private Person _selectedValue;
// the datagridview datasource, which you neet to set
private IEnumerable<Person> _gridDataSource =
new List<Person>()
{
new Person {FirstName="Bob",LastName="Smith" },
new Person {FirstName="Joe",LastName="Doe"}
};
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode== Keys.F3)
{
var btnOk = new Button() { Text = "Ok", Anchor= AnchorStyles.None };
var btnCancel = new Button() { Text = "Cancel",Anchor= AnchorStyles.Right };
var dg = new DataGridView();
var bs = new BindingSource();
bs.DataSource = _gridDataSource;
dg.DataSource = bs;
dg.Dock = DockStyle.Fill;
dg.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
//setup a layout wich will nicely fit to the window
var layout = new TableLayoutPanel();
layout.Controls.Add(dg, 0, 0);
layout.SetColumnSpan(dg, 2);
layout.Controls.Add(btnCancel, 0, 1);
layout.Controls.Add(btnOk, 1, 1);
layout.RowStyles.Add(new RowStyle(SizeType.Percent));
layout.RowStyles.Add(new RowStyle(SizeType.AutoSize));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
layout.Dock = DockStyle.Fill;
//create a new window and add the cotnrols
var window = new Form();
window.StartPosition = FormStartPosition.CenterScreen;
window.Controls.Add(layout);
// set the ok and cancel buttons of the window
window.AcceptButton = btnOk;
window.CancelButton = btnCancel;
btnOk.Click += (s, ev) => { window.DialogResult = DialogResult.OK; };
btnCancel.Click += (s, ev) => { window.DialogResult = DialogResult.Cancel; };
//here we show the window as a dialog
if (window.ShowDialog() == DialogResult.OK)
{
_selectedValue =(Person) bs.Current;
MessageBox.Show(_selectedValue.FirstName);
}
}
}
I am new to C#. I am using windows forms.
As shown in screenshot, I have form1 with 4 buttons and 4 user controls.
click show UserControl1 and UserControl1 shows up.
click show UserControl2 and UserControl2 shows up.
click show UserControl3 and UserControl3 shows up.
click show UserControl4 and UserControl4 shows up.
what I want to do is: when I click Show Previous UC (on User Control4) , the previous User Control shows up.
for example:
click show UserControl2 and UserControl2 shows up.
click show UserControl4 and UserControl4 shows up.
and now I want when I click Show Previous UC, UserControl2 shows up (the previous user control).
How Can I show the previous User Control ( the last one which was shown before the current one)?
Please help me, Thank you.
public partial class Form1 : Form
{
UserControl1 UC1 = new UserControl1();
UserControl2 UC2 = new UserControl2();
UserControl3 UC3 = new UserControl3();
UserControl4 UC4 = new UserControl4();
public Form1()
{
InitializeComponent();
Controls.Add(UC1);
Controls.Add(UC2);
Controls.Add(UC3);
Controls.Add(UC4);
}
private void ShowUserControl1_Click(object sender, EventArgs e)
{
UC1.Visible = true;
UC2.Visible = false;
UC3.Visible = false;
UC4.Visible = false;
}
private void ShowUserControl2_Click(object sender, EventArgs e)
{
UC2.Visible = true;
UC1.Visible = false;
UC3.Visible = false;
UC4.Visible = false;
}
private void ShowUserControl3_Click(object sender, EventArgs e)
{
UC3.Visible = true;
UC1.Visible = false;
UC2.Visible = false;
UC4.Visible = false;
}
private void ShowUserControl4_Click(object sender, EventArgs e)
{
UC4.Visible = true;
UC3.Visible = false;
UC2.Visible = false;
UC1.Visible = false;
}
}
You need to keep track of which user control was the previous in the page (and possible also the current, unless you want to iterate the UCs to find out). Use fields for this in the page.
public partial class Form1 : Form
{
UserControl[] userControls = new []{
new UserControl1(),
new UserControl2(),
new UserControl3(),
new UserControl4()
};
UserControl previous;
UserControl current;
public Form1()
{
InitializeComponent();
foreach(var uc in UserControls)
{
uc.Click += ShowPrevControl_Click;
Controls.Add(uc);
}
}
In the event (you only need one)
private void ShowUserControl_Click(object sender, EventArgs e)
{
foreach(UserControl uc in UserControls)
{
if(uc.Name == (string)((Control)sender).Tag)
{
previous = current;
uc.Visible = true;
current = uc;
}
else
{
uc.Visible = false;
}
}
}
private void ShowPrevControl_Click(object sender, EventArgs e)
{
if (previous != null)
{
foreach(var uc in UserControls)
{
uc.Visible = false;
}
var temp = current;
previous.Visible = true;
current = previous;
previous = temp;
}
}
Set the Tag property for each button to hold the name of the UserControl it should control (UserControl1, UserControl2, UserControl3 or UserControl4).
Let all the buttons click events be handled by ShowUserControl_Click.
Create a new public event in your user controls (if all should handle clicks), that that page can handle using your ShowPrevControl_Clickmethod:
public UserControlx : UserControl
{
public event EventHandler Click;
public UserControlx()
{
Button.Click += Button_Click;
}
private void Button_Click(object sender, EventArgs e)
{
if(Click != null)
Click(this, EventArgs.Empty);
}
}
An easy solution is to add a member variable to your class.
So your class would look like:
public partial class Form1 : Form
{
UserControl prevControl;
// Etc...
So when you click the button for, say, UC2, you can set prevControl to UC2.
private void ShowUserControl2_Click(object sender, EventArgs e)
{
UC2.Visible = true;
prevControl = UC2;
UC1.Visible = false;
UC3.Visible = false;
UC4.Visible = false;
}
And on an event handler for the "Show previous control" button:
private void ShowPrevControl_Click(object sender, EventArgs e)
{
if (prevControl != null) prevControl.Visible = true;
}
UserControl is a reference in C#, which makes this possible.
I'm new to C# and I've attempted many of the solutions here on StackExchange and I've had no luck in trying to set up a control or the entire form for that matter to left click and drag the entire window. I'm working with a frameless window in visual studio 12. The closest I've come to moving the window is moving a single control with the pastebin component(last response) from this-
How do I make mousedrag inside Panel move form window?
I could only get the panel itself to move with that component.
I've tried most of the approaches but I seem get lost where I am to customize it to my own needs. I've tried WndProc override but it didn't do anything when I attempted to move the form window.
I have two panels I want to be able to drag the window with DragPanel and DragPanel2.
Here is my most recent failed approach trying to use the whole form.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
InsideMover _dragger = new InsideMover();
_dragger.ControlToMove = this.DragPanel;
}
private void close_Click(object sender, EventArgs e)
{
Close();
}
}
public class InsideMover : Component
{
/// <summary>
/// Required designer variable.
/// </summary>
private Container components = null;
public InsideMover(IContainer container)
{
///
/// Required for Windows.Forms Class Composition Designer support
///
container.Add(this);
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
public InsideMover()
{
///
/// Required for Windows.Forms Class Composition Designer support
///
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
public Control ControlToMove
{
set
{
if (_parent != null)
{
// odkvaci prijasnje evente
_parent.MouseDown -= new MouseEventHandler(_parent_MouseDown);
_parent.MouseMove -= new MouseEventHandler(_parent_MouseMove);
_parent.MouseUp -= new MouseEventHandler(_parent_MouseUp);
_parent.DoubleClick -= new EventHandler(_parent_DoubleClick);
}
_parent = value;
if (value != null)
{
// zakači se na evente od containera koji ti trebaju
_parent.MouseDown += new MouseEventHandler(_parent_MouseDown);
_parent.MouseMove += new MouseEventHandler(_parent_MouseMove);
_parent.MouseUp += new MouseEventHandler(_parent_MouseUp);
_parent.DoubleClick += new EventHandler(_parent_DoubleClick);
}
}
get
{
return _parent;
}
}
Control _parent;
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
int _lastMouseX;
int _lastMouseY;
bool _moving;
public void StartMouseDown(MouseEventArgs e)
{
_parent_MouseDown(null, e);
}
private void _parent_MouseDown(object sender, MouseEventArgs e)
{
_lastMouseX = e.X;
_lastMouseY = e.Y;
_moving = true;
}
private void _parent_MouseMove(object sender, MouseEventArgs e)
{
if (_moving)
{
Point newLocation = _parent.Location;
newLocation.X += e.X - _lastMouseX;
newLocation.Y += e.Y - _lastMouseY;
_parent.Location = newLocation;
}
}
private void _parent_MouseUp(object sender, MouseEventArgs e)
{
_moving = false;
}
private void _parent_DoubleClick(object sender, EventArgs e)
{
if (_parent is Form)
{
Form f = (Form)_parent;
if (f.WindowState == FormWindowState.Normal)
{
f.WindowState = FormWindowState.Maximized;
}
else
{
f.WindowState = FormWindowState.Normal;
}
}
}
}
}
How can I set the panels to left click drag the window?
I've tried all of the methods at the post above and the WndProc method here:
Drag borderless windows form by mouse
If you follow the answer in the link you've posted, it is using the mousemove event, whereas judging by the code you've posted, you're using the mousedown event. The mouse down event is only called once when you press a mouse button, it is not called again if you move the mouse while you keep pressing the button. Whereas the mousemove event is called whenever your pointer moves. So your best bet would be to change your mousedown event with the mousemove event i.e.
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
if that doesn't work, you can do something like this in the mousemove event, first create a Point 'prevpoint' and an offset point in the form.
Point prevpoint=new Point(0,0);
Point offset=new Point(0,0);
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
offset.X=e.X-prevpoint.X;
offset.Y=e.Y-prevpoint.Y;
prevpoint.X=e.X;
prevpoint.Y=e.Y;
this.Location = new Point(this.Location.X + offset.X, this.Location.Y + offset.Y);
}
}
I have not tested the above code but that will hopefully give you the basic idea.
How to get event for ComboBox inside of Gridview using C# Windows Application... Anyone Tell me the solution of this problem.....
Thanks in Advance...
check this http://www.eggheadcafe.com/community/aspnet/2/10098379/gridview.aspx
I think you are looking at the wrong place. For value change event, you should use your class's property changed event that is bound to that specific column in the GridView. Because, when you change value in the ComboBoxColumn, it will in turn update the value in the object that is bound to that row.
Example:
Designer generated code
`partial class Form1
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.Column1 = new System.Windows.Forms.DataGridViewComboBoxColumn();
this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// dataGridView1
//
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Column1,
this.Column2});
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.RowTemplate.Height = 24;
this.dataGridView1.Size = new System.Drawing.Size(282, 255);
this.dataGridView1.TabIndex = 0;
//
// Column1
//
this.Column1.DataPropertyName = "Value1";
this.Column1.HeaderText = "Column1";
this.Column1.Name = "Column1";
//
// Column2
//
this.Column2.DataPropertyName = "Value2";
this.Column2.HeaderText = "Column2";
this.Column2.Name = "Column2";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(282, 255);
this.Controls.Add(this.dataGridView1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.DataGridViewComboBoxColumn Column1;
private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
}`
Code Behind
`public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Column1 is
Column1.DataPropertyName = "Value1";
Column1.Items.AddRange(Enumerable.Range(1, 10).Select(i => i.ToString()).ToArray());
Column2.DataPropertyName = "Value2";
dataGridView1.DataError += new DataGridViewDataErrorEventHandler(dataGridView1_DataError);
dataGridView1.DataSource = (from obj in Enumerable.Range(1, 20)
select new Model() { Value1 = obj, Value2 = ("Value2 #" + obj.ToString()) }).ToList();
}
void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
System.Diagnostics.Debug.WriteLine(e.Exception.ToString());
}
}
class Model
{
protected Int32 _value1;
public Int32 Value1
{
get
{
return _value1;
}
set
{
// Here is your property change event
MessageBox.Show(value.ToString());
_value1 = value;
}
}
public String Value2 { get; set; }
}`