Disappearing Dynamic ComboBox - combobox

Created the following code to workout some bugs in a bigger program. That said, when I click the button to add a row, the next row is added, but the previously created ComboBox (cmboPhoneType) disappears with each new click. What am I missing how to correct? Does this maybe have something to do with the name of the control?
using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
namespace AddNewRowTest
{
public partial class Form1 : Form
{
int leftControl = 1;
ComboBox cmboPhoneType = new ComboBox();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
addLabels();
btn_AddRow.PerformClick();
}
private void btn_AddRow_Click(object sender, EventArgs e)
{
//Connection Information redacted
reConn.Open();
MySqlCommand phoneTypeCommand = new MySqlCommand("Select * from lutable_phonetype order by Type;", reConn);
MySqlDataAdapter phoneTypeAdapter = new MySqlDataAdapter();
DataTable phoneTypeTable = new DataTable();
phoneTypeAdapter.SelectCommand = phoneTypeCommand;
phoneTypeAdapter.Fill(phoneTypeTable);
this.Controls.Add(cmboPhoneType);
cmboPhoneType.Top = leftControl * 36;
cmboPhoneType.Left = 12;
cmboPhoneType.Size = new Size(100, 20);
cmboPhoneType.DataSource = phoneTypeTable;
cmboPhoneType.DisplayMember = "Type";
cmboPhoneType.ValueMember = "TypeID";
cmboPhoneType.DataBindings.Add("SelectedValue", phoneTypeTable, "TypeID");
cmboPhoneType.SelectedIndexChanged += new System.EventHandler(cmboPhoneType_SelectedIndexChanged);
MaskedTextBox msktxtPhone = new MaskedTextBox();
this.Controls.Add(msktxtPhone);
msktxtPhone.Top = leftControl * 36;
msktxtPhone.Left = 116;
msktxtPhone.Size = new Size(100, 20);
msktxtPhone.Mask = "(999) 000-0000";
reConn.Close();
leftControl++;
}
private void addLabels()
{
Label lblPhoneType = new Label();
this.Controls.Add(lblPhoneType);
lblPhoneType.Top = leftControl * 12;
lblPhoneType.Left = 12;
lblPhoneType.Text = "Phone Type";
Label lblPhoneNumber = new Label();
this.Controls.Add(lblPhoneNumber);
lblPhoneNumber.Top = leftControl * 12;
lblPhoneNumber.Left = 116;
lblPhoneNumber.Text = "Phone Number";
}
private void cmboPhoneType_SelectedIndexChanged(object sender, EventArgs e)
{
cmboPhoneType.DataBindings.Clear();
}
}
}

Your Adding a "New" Masked Text Box in your Click Event but no "New" Combo Box. Then after you Declare a new cmbophonetype you will need to move, this.Controls.Add(cmboPhoneType); down, to just before you add the SelectedIndexChanged event handler. That will keep the Combobox visible but you may have some more problems separating all of the events.

Related

C# - SendKeys GUI Buttons Bug

I've downloaded a spammer program from YouTube, and decompiled it. Here's the code:
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace SimpleSpammer
{
public class Form1 : Form
{
private IContainer components;
private TextBox textBox1;
private Button button1;
private Button button2;
private Label label1;
private LinkLabel linkLabel1;
private Label label2;
private LinkLabel linkLabel2;
private Label label3;
private Timer timer1;
private Label label4;
private TextBox textBox2;
private Label label5;
private CheckBox checkBox1;
public Form1()
{
this.components = (IContainer) null;
base.\u002Ector();
this.InitializeComponent();
}
protected override void Dispose(bool disposing)
{
if (disposing && this.components != null)
this.components.Dispose();
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.components = (IContainer) new Container();
this.textBox1 = new TextBox();
this.button1 = new Button();
this.button2 = new Button();
this.label1 = new Label();
this.linkLabel1 = new LinkLabel();
this.label2 = new Label();
this.linkLabel2 = new LinkLabel();
this.label3 = new Label();
this.timer1 = new Timer(this.components);
this.label4 = new Label();
this.textBox2 = new TextBox();
this.label5 = new Label();
this.checkBox1 = new CheckBox();
this.SuspendLayout();
this.textBox1.Location = new Point(13, 13);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new Size(259, 20);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "SPAM !";
this.textBox1.TextAlign = HorizontalAlignment.Center;
this.button1.Location = new Point(13, 39);
this.button1.Name = "button1";
this.button1.Size = new Size(75, 23);
this.button1.TabIndex = 1;
this.button1.Text = "Start";
this.button1.UseVisualStyleBackColor = true;
// ISSUE: method pointer
this.button1.Click += new EventHandler((object) this, __methodptr(button1_Click));
this.button2.Location = new Point(197, 39);
this.button2.Name = "button2";
this.button2.Size = new Size(75, 23);
this.button2.TabIndex = 2;
this.button2.Text = "Stop";
this.button2.UseVisualStyleBackColor = true;
// ISSUE: method pointer
this.button2.Click += new EventHandler((object) this, __methodptr(button2_Click));
this.label1.AutoSize = true;
this.label1.Font = new Font("Arial", 8.25f, FontStyle.Italic, GraphicsUnit.Point, (byte) 0);
this.label1.ForeColor = SystemColors.WindowFrame;
this.label1.Location = new Point(7, 216);
this.label1.Name = "label1";
this.label1.Size = new Size(275, 14);
this.label1.TabIndex = 3;
this.label1.Text = "Copyright © 2010 TheDarkJoker94. This is a freeware.";
this.linkLabel1.AutoSize = true;
this.linkLabel1.Location = new Point(30, 190);
this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.Size = new Size(162, 13);
this.linkLabel1.TabIndex = 4;
this.linkLabel1.TabStop = true;
this.linkLabel1.Text = "http://thedarkjoker94.cer33.com";
// ISSUE: method pointer
this.linkLabel1.LinkClicked += new LinkLabelLinkClickedEventHandler((object) this, __methodptr(linkLabel1_LinkClicked));
this.label2.AutoSize = true;
this.label2.Location = new Point(10, 135);
this.label2.Name = "label2";
this.label2.Size = new Size(172, 13);
this.label2.TabIndex = 5;
this.label2.Text = "Check my C# Tutorials on Youtube";
this.linkLabel2.AutoSize = true;
this.linkLabel2.Location = new Point(30, 151);
this.linkLabel2.Name = "linkLabel2";
this.linkLabel2.Size = new Size(242, 13);
this.linkLabel2.TabIndex = 6;
this.linkLabel2.TabStop = true;
this.linkLabel2.Text = "http://www.youtube.com/user/TheDarkJoker094";
// ISSUE: method pointer
this.linkLabel2.LinkClicked += new LinkLabelLinkClickedEventHandler((object) this, __methodptr(linkLabel2_LinkClicked));
this.label3.AutoSize = true;
this.label3.Location = new Point(10, 171);
this.label3.Name = "label3";
this.label3.Size = new Size(91, 13);
this.label3.TabIndex = 7;
this.label3.Text = "More Software on";
this.timer1.Interval = 500;
// ISSUE: method pointer
this.timer1.Tick += new EventHandler((object) this, __methodptr(timer1_Tick));
this.label4.AutoSize = true;
this.label4.Font = new Font("Arial", 9.75f, FontStyle.Regular, GraphicsUnit.Point, (byte) 0);
this.label4.Location = new Point(13, 73);
this.label4.Name = "label4";
this.label4.Size = new Size(88, 16);
this.label4.TabIndex = 8;
this.label4.Text = "Timer Interval:";
this.textBox2.Location = new Point(102, 72);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new Size(89, 20);
this.textBox2.TabIndex = 9;
this.textBox2.Text = "100";
this.label5.AutoSize = true;
this.label5.Font = new Font("Arial", 9.75f, FontStyle.Regular, GraphicsUnit.Point, (byte) 0);
this.label5.Location = new Point(197, 73);
this.label5.Name = "label5";
this.label5.Size = new Size(77, 16);
this.label5.TabIndex = 10;
this.label5.Text = "miliseconds";
this.checkBox1.AutoSize = true;
this.checkBox1.Checked = true;
this.checkBox1.CheckState = CheckState.Checked;
this.checkBox1.Font = new Font("Arial", 9.75f, FontStyle.Regular, GraphicsUnit.Point, (byte) 0);
this.checkBox1.Location = new Point(13, 103);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new Size(151, 20);
this.checkBox1.TabIndex = 12;
this.checkBox1.Text = "Send the ENTER key";
this.checkBox1.UseVisualStyleBackColor = true;
this.AutoScaleDimensions = new SizeF(6f, 13f);
this.AutoScaleMode = AutoScaleMode.Font;
this.ClientSize = new Size(284, 239);
this.Controls.Add((Control) this.checkBox1);
this.Controls.Add((Control) this.label5);
this.Controls.Add((Control) this.textBox2);
this.Controls.Add((Control) this.label4);
this.Controls.Add((Control) this.label3);
this.Controls.Add((Control) this.linkLabel2);
this.Controls.Add((Control) this.label2);
this.Controls.Add((Control) this.linkLabel1);
this.Controls.Add((Control) this.label1);
this.Controls.Add((Control) this.button2);
this.Controls.Add((Control) this.button1);
this.Controls.Add((Control) this.textBox1);
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "Form1";
this.ShowIcon = false;
this.Text = "SimpleSpammer";
this.ResumeLayout(false);
this.PerformLayout();
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Process.Start("http://thedarkjoker94.cer33.com/");
}
private void button1_Click(object sender, EventArgs e)
{
try
{
this.timer1.Interval = Convert.ToInt32(this.textBox2.Text);
this.timer1.Start();
}
catch (Exception ex)
{
int num = (int) MessageBox.Show("An Exception was thrown!\n" + ex.Message, "ExceptionThrown");
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (this.Focused)
return;
SendKeys.Send(this.textBox1.Text);
if (this.checkBox1.CheckState == CheckState.Checked)
SendKeys.Send("{ENTER}");
}
private void button2_Click(object sender, EventArgs e)
{
this.timer1.Stop();
}
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Process.Start("http://www.youtube.com/user/TheDarkJoker094");
}
}
}
Now, as you can see his code contains a delay field, a text field, and "Start"/"Stop" buttons.
So I've tried to make something similar, and here's the code:
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;
using System.Threading;
namespace Spammer
{
public partial class Form1 : Form
{
int delay, y = 1;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
delay = int.Parse(textBox2.Text);
timer1.Interval = delay;
timer1.Start();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
}
private void send()
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
if (this.Focused)
{
return;
}
SendKeys.Send(textBox1.Text);
}
}
}
Now, I've posted a similar question yesterday but this one is far more accurate.
In his program, I've entered some text, chose a delay of 10MS and started it. After a few seconds of sending, I've clicked the "Stop" button in his program and it stopped sending keys immediately.
Now... When I ran my program, and started sending keys (with a 10MS delay), I let it run for a few seconds, and then I pressed "Stop". Nothing happened, and "Stop" didn't even click. It just has shown a blue frame around it and I wasn't able to click it.
And of course, because of this, it didn't stop sending keys.
So, why did it work perfectly in his program but it doesn't work at all in my program?

unable to set Row.Readonly=false in Datagridview in winforms

I have a datagridview with its ReadOnly set true to prevent people editing.
then I have a button on each row. when I click on a specific button, I wrote:
private void DGGrade_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex > 0 && e.ColumnIndex == DGGrade.Columns["Edit"].Index)
{
DGGrade.Rows[DGGrade.CurrentCell.RowIndex].ReadOnly = false;
DGGrade.Rows[DGGrade.CurrentCell.RowIndex].DefaultCellStyle.BackColor = Color.White;
}
But it is not working. please help
I do not know the reason why it is not working but as far as i can tell from my test runs it has to deal how the data is bound. If you use dataGridView1.DataSource = GetDataSource(); then it did not work in my tests. I have read once about some of the drawbacks of automated binding but i could not find it. Here is the code that works. A row is only in EditMode after the User has clicked the button Edit in the corresponding row. I will be back later - let me know if you need more pointers.
public partial class Form1 : Form
{
int rowIndexOfEditableRow = -1;
public Form1() {
InitializeComponent();
CreateDataGridView(dataGridView1);
SetExistingDataGridViewRowsReadOnly();
this.dataGridView1.Columns.Add(GetBtnColumn());
}
private void SetExistingDataGridViewRowsReadOnly() {
DataGridViewRowCollection rows = this.dataGridView1.Rows;
foreach (DataGridViewRow row in rows) {
row.ReadOnly = true;
}
}
It seems that the grid must be filled manually - at least this way the change of ReadOnly works
public void CreateDataGridView(DataGridView dgv)
{
dgv.ColumnCount = 3;
dgv.Columns[0].Name = "Id";
dgv.Columns[1].Name = "Lastname";
dgv.Columns[2].Name = "City";
dgv.BackgroundColor = Color.Gray;
AddRowsToDataGridView(dgv);
}
private void AddRowsToDataGridView(DataGridView dgv)
{
string[] row1 = new string[]{"1", "Muller", "Seattle"};
string[] row2 = new string[]{"2", "Arkan", "Austin"};
string[] row3 = new string[]{"3", "Cooper", "New York"};
object[] rows = new object[] { row1, row2, row3 };
foreach (string[] rowArray in rows)
{
dgv.Rows.Add(rowArray);
}
}
Helper method to create a column with a button
public DataGridViewButtonColumn GetBtnColumn()
{
DataGridViewButtonColumn btnColumn = new DataGridViewButtonColumn();
btnColumn.HeaderText = "Edit";
btnColumn.Text = "Edit";
btnColumn.UseColumnTextForButtonValue = true;
return btnColumn;
}
Event handler checks if the user has clicked the edit button. In this case the current row will be set to ReadOnly = false. This allows that the user to edit the row. To emphasize it i changed the background color of the row.
private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
int colIndex = e.ColumnIndex;
int rowIndex = e.RowIndex;
Type cellType = dataGridView1.Columns[colIndex].CellType;
if (cellType == typeof(DataGridViewButtonCell))
{
dataGridView1.Rows[rowIndex].ReadOnly = false;
dataGridView1.Rows[rowIndex].DefaultCellStyle.BackColor = Color.GreenYellow;
this.rowIndexOfEditableRow = rowIndex;
label1.Text = rowIndexOfEditableRow.ToString() + " " + colIndex.ToString();
}
}
If the Row-leave-Event is fired the style is reset and the global parameter which row is editable is set to the initial value
private void DataGridView1_RowLeave(object sender, DataGridViewCellEventArgs e)
{
int rowIndex = e.RowIndex;
dataGridView1.Rows[rowIndex].ReadOnly = true;
dataGridView1.Rows[rowIndex].DefaultCellStyle.BackColor = Color.White;
this.rowIndexOfEditableRow = -1;
}
}
The above code contains all (except the designer files) that you need to create this demo:

Finding controls in Windows Forms C# .NET?

Using Windows Forms, two link labels are created dynamically. When the user clicks on anyone of links labels, one dynamic form is created. In that form I created one data grid, a text box and a button placed dynamically (in that dynamic form). Now I want to access the dynamic data grid in the dynamic button click event. How can I do that?
private void Users_Load(object sender, EventArgs e)
{
da = new SqlDataAdapter("Usp_Get_Employees", con);
ds = new DataSet();
da.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
string somecode = i.ToString() + ds.Tables[0].Rows[i]["eid"].ToString();
LinkLabel lbluser = new LinkLabel();
lbluser.Name = ds.Tables[0].Rows[i]["eid"].ToString();
lbluser.Text = ds.Tables[0].Rows[i]["ename"].ToString();
lbluser.Location = new System.Drawing.Point(40, i * 40);
lbluser.Size = new System.Drawing.Size(50, 30);
Controls.Add(lbluser);
lbluser.Click += new EventHandler(lbluser_Click);
}
}
}
void lbluser_Click(object sender, EventArgs e)
{
LinkLabel lnkClis = (LinkLabel)sender;
Form frm = new Form();
frm.Name = lnkClis.Name;
frm.Text = lnkClis.Text;
frm.Show();
DataGrid dtgrd = new DataGrid();
dtgrd.Location = new System.Drawing.Point(10, 1 * 40);
dtgrd.Name = lnkClis.Name;
names = lnkClis.Name;
TextBox tx = new TextBox();
tx.Location = new System.Drawing.Point(10, 5 * 40);
tx.Size = new Size(80, 30);
tx.Multiline = true;
tx.LostFocus += new EventHandler(tx_LostFocus);
Button btn = new Button();
btn.Location = new System.Drawing.Point(10, 7 * 40);
btn.Size = new System.Drawing.Size(50, 30);
btn.Name = lnkClis.Name;
btn.Click += new EventHandler(btn_Click);
frm.Controls.Add(dtgrd);
frm.Controls.Add(tx);
frm.Controls.Add(btn);
}
// Now I am trying to access the data grid in the btn_click event
void btn_Click(object sender, EventArgs e)
{
Button btsave = (Button)sender;
string eid = btsave.Name;
object grd = btsave.Parent.Controls.Find("dtgrd", true).FirstOrDefault();
((DataGrid)grd).DataSource = ds.Tables[0];
}
Now I am getting an error object set of instances of an object at:
((DataGrid)grd).DataSource = ds.Tables[0];
The exception message you have written:
Now I am getting an error object set of instances of an object at
makes no sense, but it looks like
Object reference not set to an instance of an object
If this is the case, I think the error lays in Find method call. According to documentation:
Searches for controls by their Name property and builds an array of all the controls that match.
In your button click handler you assume that grid is called dtgrd, but while you create a grid you name it like this:
dtgrd.Name = lnkClis.Name;
it will suffice if you change this line to:
dtgrd.Name = "dtgrd";
Having said that, you should consider using an anonymous method for the button click handler. It will eliminate need for calling the Find method in the first place.
void lbluser_Click(object sender, EventArgs e)
{
//...
DataGrid dtgrd = new DataGrid();
//...
Button btn = new Button();
//...
btn.Click += (sender,args)=> dtgrd.DataSource = ds.Tables[0];
Try the following code
public Form1()
{
Form f1 = new Form();
f1.Text = "New Form";
TextBox t1 = new TextBox();
t1.Top = 0;
t1.Name = "t1";
t1.Visible = true;
f1.Controls.Add(t1);
Button b1 = new Button();
b1.Top = 30;
b1.Name = "b1";
b1.Text = "Click";
b1.Click += b1_Click;
f1.Controls.Add(b1);
f1.Show();
}
public void b1_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
object txt = btn.Parent.Controls.Find("t1", false).First();
((TextBox)txt).Text = "Hi, you have clicked me.";
}
I modified Nitesh's code a bit. Just capture the textbox in the click handler using a lambda:
public Form1()
{
Form f1 = new Form();
f1.Text = "New Form";
TextBox t1 = new TextBox();
t1.Top = 0;
t1.Name = "t1";
t1.Visible = true;
f1.Controls.Add(t1);
Button b1 = new Button();
b1.Top = 30;
b1.Name = "b1";
b1.Text = "Click";
b1.Click += (sender, args) => MessageBox.Show("The text is: " + t1.Text);
f1.Controls.Add(b1);
f1.Show();
}
The error you are getting is from the statement (as the grd object is null):
((DataGrid)grd).DataSource = ds.Tables[0];
Since you are trying to catch hold of a dynamic control, it's good have a proper null checks, type checks, and error handling. Something like this:
if(grd != null && grd is DataGrid)
((DataGrid)grd).DataSource = ds.Tables[0];

Get textbox value

If I start my form, write something in my textbox and then try to get the textbox value, then I get null. How can I get the textbox value? If I add a button and try to get the value, then it works. But I'm trying to do it without the button. I am using a WPF form. This is my code:
public partial class _2band : Page
{
public _2band()
{
InitializeComponent();
UpdateLayout();
RFIDI();
vardasBox1.Text = "";
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();
}
// MainWondow mainas = new MainWondow();
DB db = new DB();
string pavad;
string vardas;
int status;
string s = "";
string s0 = "";
RfidApi Api = new RfidApi();
private System.Windows.Threading.DispatcherTimer dispatcherTimer;
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
Api.nuskaitymas(out s0);
if (s0 != null)
{
s = s0;
vardas = vardasBox1.Text;
}
}

TreeView in Winforms and focus problem

Can anyone please explain to my why the form in the code below gets out of focus when selecting a treenode in the tree? What should happen is that the form/button should get the focus when the tree disappears like the listview example but it doesn't.
Code example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace FocusTest
{
public partial class Form1 : Form
{
#region Generated
/// <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()
{
System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem("Item1");
System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem("Item2");
System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem("Item3");
System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("Node0");
System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("Node1");
System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("Node2");
this.button1 = new System.Windows.Forms.Button();
this.listView1 = new System.Windows.Forms.ListView();
this.button2 = new System.Windows.Forms.Button();
this.treeView1 = new System.Windows.Forms.TreeView();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(12, 12);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// listView1
//
this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
listViewItem1,
listViewItem2,
listViewItem3
});
this.listView1.Location = new System.Drawing.Point(12, 41);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(121, 97);
this.listView1.TabIndex = 1;
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.Visible = false;
this.listView1.SelectedIndexChanged += new System.EventHandler(this.listView1_SelectedIndexChanged);
this.listView1.View = View.List;
//
// button2
//
this.button2.Location = new System.Drawing.Point(310, 11);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 2;
this.button2.Text = "button2";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// treeView1
//
this.treeView1.Location = new System.Drawing.Point(310, 41);
this.treeView1.Name = "treeView1";
treeNode1.Name = "Node0";
treeNode1.Text = "Node0";
treeNode2.Name = "Node1";
treeNode2.Text = "Node1";
treeNode3.Name = "Node2";
treeNode3.Text = "Node2";
this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
treeNode1,
treeNode2,
treeNode3});
this.treeView1.Size = new System.Drawing.Size(121, 97);
this.treeView1.TabIndex = 3;
this.treeView1.Visible = false;
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(760, 409);
this.Controls.Add(this.treeView1);
this.Controls.Add(this.button2);
this.Controls.Add(this.listView1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.ListView listView1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.TreeView treeView1;
#endregion
public Form1()
{
InitializeComponent();
}
#region TreeView
private void button2_Click(object sender, EventArgs e)
{
ToggleTreeView();
}
private void ToggleTreeView()
{
if (treeView1.Visible)
{
Controls.Remove(treeView1);
treeView1.Visible = false;
}
else
{
Controls.Add(treeView1);
treeView1.Size = new Size(300, 400);
treeView1.Location = PointToClient(PointToScreen(new System.Drawing.Point(button2.Location.X, button2.Location.Y + button2.Height)));
this.treeView1.BringToFront();
treeView1.Visible = true;
treeView1.Select();
}
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
ToggleTreeView();
}
#endregion
#region ListView
private void button1_Click(object sender, EventArgs e)
{
ToggleListView();
}
private void ToggleListView()
{
if (listView1.Visible)
{
Controls.Remove(listView1);
listView1.Visible = false;
}
else
{
Controls.Add(listView1);
listView1.Size = new Size(300, 400);
listView1.Location = PointToClient(PointToScreen(new System.Drawing.Point(button1.Location.X, button1.Location.Y + button1.Height)));
this.listView1.BringToFront();
listView1.Visible = true;
listView1.Select();
}
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listView1.Visible)
ToggleListView();
}
#endregion
}
}
Here is the problem and the fix.
TreeView re-grabs focus on Ctrl+Click
I can't explain why the form loses focus, but the problem seems to be the Controls.Remove(treeView1); line. If you remove the Controls.Remove and Controls.Add lines, then it seems to behave better.
Is there a reason why you are removing the treeView from the list of control? Just setting the visibility flag to false will cause the treeView to disappear after the user makes their selection.
EDIT:
In response to your comment:
My guess is that after treeView1_AfterSelect is called, the TreeView is setting focus to itself. Which in your code is impossible because you've removed the control from the form.
To test this theory, I added a timer, replaced the code with:
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
timer1.Enabled = true;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
ToggleTreeView();
timer1.Stop();
timer1.Enabled = false;
}
Now it works fine. So I'm guessing that the TreeView is calling this.Focus after it has fired the AfterSelect event. (That is just a guess, maybe someone else knows more about the internals them me:) )
And the reason why this is working with the ListView, is that it does not set focus to itself after listView1_SelectedIndexChanged.

Resources