当我设置不同组合框的数据集时,`SelectedIndexChanged` 触发事件
`SelectedIndexChanged` fires event when I set dataset of a different combobox
这是Windows Mobile 6.5(.net精简版)在Windows Forms中出现的问题。我创建了一个包含两个用户控件的表单,每个控件包含一个组合框。
当我加载第二个用户控件时,我填充组合框并触发第一个用户控件的组合框的 _SelectedIndexChanged
。
只有在第一个用户控件中有控件数据网格时才会发生此错误。
如果您删除数据网格,所有事件都是正确的。
public partial class Form1 : Form
{
static void Main(string[] args)
{
Application.Run(new Form1());
}
private UserControl1 userControl1 = null;
private UserControl2 userControl2 = null;
public Form1()
{
InitializeComponent();
InitializeUserControl();
}
private void InitializeUserControl()
{
InitiliazeTab1();
InitiliazeTab2();
}
private void InitiliazeTab1()
{
userControl1 = new UserControl1();
userControl1.Dock = DockStyle.Fill;
TabPage oTabpage1 = new TabPage();
oTabpage1.Name = "tabSeleccionTipo1";
oTabpage1.Text = "Tipo1 ";
oTabpage1.Controls.Add(userControl1);
tabControl1.TabPages.Add(oTabpage1);
userControl1.LoadComponent();
}
private void InitiliazeTab2()
{
userControl2 = new UserControl2();
userControl2.Dock = DockStyle.Fill;
TabPage oTabpage2 = new TabPage();
oTabpage2.Name = "tabSeleccionTipo2";
oTabpage2.Text = "Tipo2 ";
oTabpage2.Controls.Add(userControl2);
tabControl1.TabPages.Add(oTabpage2);
userControl2.LoadComponent();
}
}
partial class Form1
{
/// <summary>
/// Variable del diseñador requerida.
/// </summary>
private System.ComponentModel.IContainer components = null;
private System.Windows.Forms.MainMenu mainMenu1;
/// <summary>
/// Limpiar los recursos que se estén usando.
/// </summary>
/// <param name="disposing">true si los recursos administrados se deben eliminar; en caso contrario, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Código generado por el Diseñador de Windows Forms
/// <summary>
/// Método necesario para admitir el Diseñador. No se puede modificar
/// el contenido del método con el editor de código.
/// </summary>
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Location = new System.Drawing.Point(0, 0);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(240, 265);
this.tabControl1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoScroll = true;
this.ClientSize = new System.Drawing.Size(240, 268);
this.Controls.Add(this.tabControl1);
this.Menu = this.mainMenu1;
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabControl1;
}
用户控件是 UserControl1
和 UserControl2
。
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public void LoadComponent()
{
this.comboBox1.ValueMember = "Clave";
this.comboBox1.DisplayMember = "Description";
comboBox1.DataSource = getList();
}
private List<Item> getList()
{
List<Item> list = new List<Item>();
list.Add(new Item("0", "zero"));
list.Add(new Item("1", "uno"));
list.Add(new Item("2", "dos"));
list.Add(new Item("3", "tres"));
list.Add(new Item("4", "cuatro"));
return new List<Item>(list);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show("Listo 1 ^^ SelectedIndexChanged ");
}
}
partial class UserControl1
{
/// <summary>
/// Variable del diseñador requerida.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Limpiar los recursos que se estén usando.
/// </summary>
/// <param name="disposing">true si los recursos administrados se deben eliminar; en caso contrario, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Código generado por el Diseñador de componentes
/// <summary>
/// Método necesario para admitir el Diseñador. No se puede modificar
/// el contenido del método con el editor de código.
/// </summary>
private void InitializeComponent()
{
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.dataGrid1 = new System.Windows.Forms.DataGrid();
this.SuspendLayout();
//
// comboBox1
//
this.comboBox1.Location = new System.Drawing.Point(24, 24);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(163, 22);
this.comboBox1.TabIndex = 6;
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
//
// dataGrid1
//
this.dataGrid1.BackgroundColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))));
this.dataGrid1.Location = new System.Drawing.Point(24, 89);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(163, 134);
this.dataGrid1.TabIndex = 7;
//
// UserControl1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.Controls.Add(this.dataGrid1);
this.Controls.Add(this.comboBox1);
this.Name = "UserControl1";
this.Size = new System.Drawing.Size(216, 266);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.DataGrid dataGrid1;
}
public partial class UserControl2 : UserControl
{
public UserControl2()
{
InitializeComponent();
}
public void LoadComponent()
{
this.comboBox2.ValueMember = "Clave";
this.comboBox2.DisplayMember = "Description";
this.comboBox2.DataSource = getList();
}
public List<Item> getList()
{
List<Item> list = new List<Item>();
list.Add(new Item("0", "zero"));
list.Add(new Item("1", "uno"));
list.Add(new Item("2", "dos"));
list.Add(new Item("3", "tres"));
return new List<Item>(list);
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show("Listo 2 ^^ SelectedIndexChanged ");
}
}
partial class UserControl2
{
/// <summary>
/// Variable del diseñador requerida.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Limpiar los recursos que se estén usando.
/// </summary>
/// <param name="disposing">true si los recursos administrados se deben eliminar; en caso contrario, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Código generado por el Diseñador de componentes
/// <summary>
/// Método necesario para admitir el Diseñador. No se puede modificar
/// el contenido del método con el editor de código.
/// </summary>
private void InitializeComponent()
{
this.comboBox2 = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// comboBox2
//
this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
this.comboBox2.Location = new System.Drawing.Point(21, 27);
this.comboBox2.Name = "comboBox2";
this.comboBox2.Size = new System.Drawing.Size(163, 22);
this.comboBox2.TabIndex = 0;
this.comboBox2.SelectedIndexChanged += new System.EventHandler(this.comboBox2_SelectedIndexChanged);
//
// UserControl2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.Controls.Add(this.comboBox2);
this.Name = "UserControl2";
this.Size = new System.Drawing.Size(216, 266);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox comboBox2;
}
这是真实代码的简化版本。为什么当我加载第二个用户控件的组合框的数据源时会触发此事件?
call process pool 事件池过程的图像。
尝试改为订阅 SelectionChangeCommitted 活动
这样当以编程方式进行更改时它不会触发,这是数据源加载的情况
首先进行一些细微的外观更改:
写入
private List<Item> getList()
{
...
return list;
}
而不是
public List<Item> getList()
{
...
return new List<Item>(list);
}
然后移动事件处理程序赋值:
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
从设计器代码到 LoadComponent()
public void LoadComponent()
{
this.comboBox1.ValueMember = "Clave";
this.comboBox1.DisplayMember = "Description";
comboBox1.DataSource = getList();
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
}
可以通过从第一个加载的 UserControl 中删除 DataGrid 来解决此问题。例如,如果 DataGrid 在第二个加载的 UserControl 上,则不会显示该问题:
private void InitializeUserControl()
{
InitiliazeTab2();
InitiliazeTab1();
}
无法找到根本原因,即为什么在第一个 UserControl 中加载 DataGrid 时触发 ComboBox SelectedIndexChanged 事件。对此没有合乎逻辑的文档化描述,我也不知道如何调试 Compact Framework 的事件冒泡。
为了方便其他人的测试,这里有一个 VS2005 项目可以玩:https://github.com/hjgode/Whosebug/tree/master/SmartDeviceProject1
我已经决定在每个用户控件中合并一个数据网格。这个错误不合逻辑,应该是框架库错误。
谢谢。
这是Windows Mobile 6.5(.net精简版)在Windows Forms中出现的问题。我创建了一个包含两个用户控件的表单,每个控件包含一个组合框。
当我加载第二个用户控件时,我填充组合框并触发第一个用户控件的组合框的 _SelectedIndexChanged
。
只有在第一个用户控件中有控件数据网格时才会发生此错误。
如果您删除数据网格,所有事件都是正确的。
public partial class Form1 : Form
{
static void Main(string[] args)
{
Application.Run(new Form1());
}
private UserControl1 userControl1 = null;
private UserControl2 userControl2 = null;
public Form1()
{
InitializeComponent();
InitializeUserControl();
}
private void InitializeUserControl()
{
InitiliazeTab1();
InitiliazeTab2();
}
private void InitiliazeTab1()
{
userControl1 = new UserControl1();
userControl1.Dock = DockStyle.Fill;
TabPage oTabpage1 = new TabPage();
oTabpage1.Name = "tabSeleccionTipo1";
oTabpage1.Text = "Tipo1 ";
oTabpage1.Controls.Add(userControl1);
tabControl1.TabPages.Add(oTabpage1);
userControl1.LoadComponent();
}
private void InitiliazeTab2()
{
userControl2 = new UserControl2();
userControl2.Dock = DockStyle.Fill;
TabPage oTabpage2 = new TabPage();
oTabpage2.Name = "tabSeleccionTipo2";
oTabpage2.Text = "Tipo2 ";
oTabpage2.Controls.Add(userControl2);
tabControl1.TabPages.Add(oTabpage2);
userControl2.LoadComponent();
}
}
partial class Form1
{
/// <summary>
/// Variable del diseñador requerida.
/// </summary>
private System.ComponentModel.IContainer components = null;
private System.Windows.Forms.MainMenu mainMenu1;
/// <summary>
/// Limpiar los recursos que se estén usando.
/// </summary>
/// <param name="disposing">true si los recursos administrados se deben eliminar; en caso contrario, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Código generado por el Diseñador de Windows Forms
/// <summary>
/// Método necesario para admitir el Diseñador. No se puede modificar
/// el contenido del método con el editor de código.
/// </summary>
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Location = new System.Drawing.Point(0, 0);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(240, 265);
this.tabControl1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoScroll = true;
this.ClientSize = new System.Drawing.Size(240, 268);
this.Controls.Add(this.tabControl1);
this.Menu = this.mainMenu1;
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabControl1;
}
用户控件是 UserControl1
和 UserControl2
。
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public void LoadComponent()
{
this.comboBox1.ValueMember = "Clave";
this.comboBox1.DisplayMember = "Description";
comboBox1.DataSource = getList();
}
private List<Item> getList()
{
List<Item> list = new List<Item>();
list.Add(new Item("0", "zero"));
list.Add(new Item("1", "uno"));
list.Add(new Item("2", "dos"));
list.Add(new Item("3", "tres"));
list.Add(new Item("4", "cuatro"));
return new List<Item>(list);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show("Listo 1 ^^ SelectedIndexChanged ");
}
}
partial class UserControl1
{
/// <summary>
/// Variable del diseñador requerida.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Limpiar los recursos que se estén usando.
/// </summary>
/// <param name="disposing">true si los recursos administrados se deben eliminar; en caso contrario, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Código generado por el Diseñador de componentes
/// <summary>
/// Método necesario para admitir el Diseñador. No se puede modificar
/// el contenido del método con el editor de código.
/// </summary>
private void InitializeComponent()
{
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.dataGrid1 = new System.Windows.Forms.DataGrid();
this.SuspendLayout();
//
// comboBox1
//
this.comboBox1.Location = new System.Drawing.Point(24, 24);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(163, 22);
this.comboBox1.TabIndex = 6;
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
//
// dataGrid1
//
this.dataGrid1.BackgroundColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))));
this.dataGrid1.Location = new System.Drawing.Point(24, 89);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(163, 134);
this.dataGrid1.TabIndex = 7;
//
// UserControl1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.Controls.Add(this.dataGrid1);
this.Controls.Add(this.comboBox1);
this.Name = "UserControl1";
this.Size = new System.Drawing.Size(216, 266);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.DataGrid dataGrid1;
}
public partial class UserControl2 : UserControl
{
public UserControl2()
{
InitializeComponent();
}
public void LoadComponent()
{
this.comboBox2.ValueMember = "Clave";
this.comboBox2.DisplayMember = "Description";
this.comboBox2.DataSource = getList();
}
public List<Item> getList()
{
List<Item> list = new List<Item>();
list.Add(new Item("0", "zero"));
list.Add(new Item("1", "uno"));
list.Add(new Item("2", "dos"));
list.Add(new Item("3", "tres"));
return new List<Item>(list);
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show("Listo 2 ^^ SelectedIndexChanged ");
}
}
partial class UserControl2
{
/// <summary>
/// Variable del diseñador requerida.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Limpiar los recursos que se estén usando.
/// </summary>
/// <param name="disposing">true si los recursos administrados se deben eliminar; en caso contrario, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Código generado por el Diseñador de componentes
/// <summary>
/// Método necesario para admitir el Diseñador. No se puede modificar
/// el contenido del método con el editor de código.
/// </summary>
private void InitializeComponent()
{
this.comboBox2 = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// comboBox2
//
this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
this.comboBox2.Location = new System.Drawing.Point(21, 27);
this.comboBox2.Name = "comboBox2";
this.comboBox2.Size = new System.Drawing.Size(163, 22);
this.comboBox2.TabIndex = 0;
this.comboBox2.SelectedIndexChanged += new System.EventHandler(this.comboBox2_SelectedIndexChanged);
//
// UserControl2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.Controls.Add(this.comboBox2);
this.Name = "UserControl2";
this.Size = new System.Drawing.Size(216, 266);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox comboBox2;
}
这是真实代码的简化版本。为什么当我加载第二个用户控件的组合框的数据源时会触发此事件?
call process pool 事件池过程的图像。
尝试改为订阅 SelectionChangeCommitted 活动
这样当以编程方式进行更改时它不会触发,这是数据源加载的情况
首先进行一些细微的外观更改:
写入
private List<Item> getList()
{
...
return list;
}
而不是
public List<Item> getList()
{
...
return new List<Item>(list);
}
然后移动事件处理程序赋值:
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
从设计器代码到 LoadComponent()
public void LoadComponent()
{
this.comboBox1.ValueMember = "Clave";
this.comboBox1.DisplayMember = "Description";
comboBox1.DataSource = getList();
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
}
可以通过从第一个加载的 UserControl 中删除 DataGrid 来解决此问题。例如,如果 DataGrid 在第二个加载的 UserControl 上,则不会显示该问题:
private void InitializeUserControl()
{
InitiliazeTab2();
InitiliazeTab1();
}
无法找到根本原因,即为什么在第一个 UserControl 中加载 DataGrid 时触发 ComboBox SelectedIndexChanged 事件。对此没有合乎逻辑的文档化描述,我也不知道如何调试 Compact Framework 的事件冒泡。
为了方便其他人的测试,这里有一个 VS2005 项目可以玩:https://github.com/hjgode/Whosebug/tree/master/SmartDeviceProject1
我已经决定在每个用户控件中合并一个数据网格。这个错误不合逻辑,应该是框架库错误。
谢谢。