索引改變時即觸發(fā)嗎,可以通過編程觸發(fā)
值改變時觸發(fā),可以通過編程觸發(fā)
在設(shè)定datasource和displaymember和valuemember時,以及手動改變combobox索引和值時都不觸發(fā)該事件, 只是在界面選擇combobox不同值時觸發(fā),即只有通過界面點擊修改combobox的值才會觸發(fā)此事件
1、SelectedIndexChanged和SelectedValueChanged可以通過編程的方式更改屬性而觸發(fā)事件,但SelectionChangeCommitted事件必須由用戶操作選定選項才能觸發(fā)。
2、在初始化時(設(shè)置源)SelectedIndexChanged和SelectedValueChanged都會被調(diào)用,而SelectionChangeCommitted沒有這個問題。
關(guān)于在編程時通過設(shè)置DataSource, DisplayMember, ValueMember不同順序均可觸發(fā)SelectedIndexChanged事件和SelectedValueChanged事件的次數(shù),但是不會觸發(fā)SelectionChangeCommitted
this.comboBox1.DisplayMember = "userName"; (不觸發(fā))
this.comboBox1.ValueMember = "userAge"; (只觸發(fā)SelectedValueChanged)
this.comboBox1.DataSource = dt; (都觸發(fā))
SelectedValueChanged觸發(fā)兩次(總是先觸發(fā))SelectedIndexChanged,觸發(fā)一次 (設(shè)置DisplayMember屬性時不觸發(fā)兩種事件)
this.comboBox1.ValueMember = "userAge"; (只觸發(fā)SelectedValueChanged)
this.comboBox1.DisplayMember = "userName";(不觸發(fā))
this.comboBox1.DataSource = dt; (兩者都觸發(fā))
同上,SelectedValueChanged觸發(fā)兩次(總是先觸發(fā))SelectedIndexChanged,觸發(fā)一次 (設(shè)置DisplayMember屬性時不觸發(fā)兩種事件)
this.comboBox1.DataSource = dt; (都觸發(fā))
this.comboBox1.DisplayMember = "userName";(都觸發(fā))
this.comboBox1.ValueMember = "userAge";(只觸發(fā)SelectedValueChanged事件)
SelectedValueChanged觸發(fā)三次(總是先觸發(fā))SelectedIndexChanged,觸發(fā)兩次 (設(shè)置DisplayMember屬性時不觸發(fā)兩種事件)
this.comboBox1.DataSource = dt; (都觸發(fā))
this.comboBox1.ValueMember = "userAge";(都觸發(fā)) 其中SelectedValueChanged觸發(fā)兩次
this.comboBox1.DisplayMember = "userName";(都觸發(fā))
SelectedValueChanged觸發(fā)四次(總是先觸發(fā))SelectedIndexChanged,觸發(fā)三次 (設(shè)置DisplayMember屬性時不觸發(fā)兩種事件)
說明:當設(shè)置了DataSource 屬性后,SelectedValue 屬性值會默認為第一行(所以會觸發(fā)SelectedIndexChanged事件和SelectedValueChanged事件),因此,如果不希望ComboBox自動選擇第一行,還需在設(shè)置完DataSource 后自行將SelectedValue 設(shè)為“”。
ComboBox最經(jīng)常使用的事件就是SelectedIndexChanged。但在將ComboBox綁定到某個數(shù)據(jù)源的過程中,會觸發(fā)SelectedIndexChanged
事件,而這個時候用戶并沒有選擇內(nèi)容,其SelectedValue也不是對應(yīng)字段的值。那么時寫在SelectedIndexChanged中的處理代碼就會因為SelectedValue的內(nèi)容不正確引發(fā)異常。
一般網(wǎng)上找到的方法是添加一個標記位,在綁定前設(shè)置為false,綁定完成后設(shè)置回true。
void BindComboBox()
{
flag=false;
ComboxBox1.ValueMember="ValueColumn";
ComboxBox1.DisplayMember="DisplayColumn";
ComboxBox1.DataSource=DataTable1;
flag=true;
}
private void ComboxBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if(flag)
{
//Do something
}
}
另外還有一種辦法,就是在綁定前,將SelectedIndexChanged的委托去掉,等綁定完成后,再添加事件委托。
void BindComboBox()
{ //去除委托
ComboBox1.SelectedIndexChanged -= new EventHandler(ComboBox1_SelectedIndexChanged);
ComboBox1.DataSource = null;
ComboBox1.ValueMember = "ValueColumn";
ComboBox1.DataSource = DataTable1;
//添加委托
ComboBox1.SelectedIndexChanged += new EventHandler(ComboBox1_SelectedIndexChanged);
ComboBox1.DisplayMember = "DisplayColumn";
}
兩種方法都可以,但是之間的優(yōu)劣暫時沒去比較。感覺好像處理一下委托會好點。因為這種辦法真的減少了事件的激發(fā)次數(shù)。
不知道還有沒有其他解決方案呢?
另,貼上一段完整的代碼例子。這個例子是訪問SqlServer數(shù)據(jù)庫的AdventureWorks,通過ProductCategory和ProductSubCategory兩級目錄分類去查看Product表的內(nèi)容。分別使用兩個ComboBox和DataGridView完成數(shù)據(jù)綁定。效果就是選擇之后會聯(lián)動改變相關(guān)內(nèi)容。
public partial class frmProduct : Form
{
DataSet DS = new DataSet();
String ConnectionString = "integrated security=true; database=AdventureWorks; server=localhost; ";
public frmProduct()
{
InitializeComponent();
}
private void frmProduct_Load(object sender, EventArgs e)
{
SqlDataAdapter da = new SqlDataAdapter("select ProductCategoryID,[Name] from Production.ProductCategory", ConnectionString)
;
cbbCategories.SelectedIndexChanged -= new EventHandler(cbbCategories_SelectedIndexChanged);
da.Fill(DS, "ProductCategory");
cbbCategories.DataSource = null;
cbbCategories.ValueMember = "ProductCategoryID";
cbbCategories.DataSource = DS.Tables["ProductCategory"];
cbbCategories.SelectedIndexChanged += new EventHandler(cbbCategories_SelectedIndexChanged);
cbbCategories.DisplayMember = "Name";//這句放在事件委托之后才會有聯(lián)動效果,下同
}
private void cbbCategories_SelectedIndexChanged(object sender, EventArgs e)
{
SqlDataAdapter da = new SqlDataAdapter("select ProductSubCategoryID,[Name] from Production.ProductSubCategory where ProductCategoryID=" + cbbCategories.SelectedValue.ToString(), ConnectionString)
;
if (DS.Tables["ProductSubCategory"] != null)
{
DS.Tables["ProductSubCategory"].Clear();
}
da.Fill(DS, "ProductSubCategory");
cbbSubCategories.SelectedIndexChanged -= new EventHandler(cbbSubCategories_SelectedIndexChanged);
cbbSubCategories.DataSource = null;
cbbSubCategories.ValueMember = "ProductSubCategoryID";
cbbSubCategories.DataSource = DS.Tables["ProductSubCategory"];
cbbSubCategories.SelectedIndexChanged += new EventHandler(cbbSubCategories_SelectedIndexChanged);
cbbSubCategories.DisplayMember = "Name";
}
private void cbbSubCategories_SelectedIndexChanged(object sender, EventArgs e)
{
if (cbbSubCategories.SelectedIndex == -1)
return;
SqlDataAdapter da=new SqlDataAdapter("select * from Production.Product where ProductSubCategoryID=" + cbbSubCategories.SelectedValue.ToString(), ConnectionString);
dgvProduct.DataSource = null;
if (DS.Tables["Product"] != null)
DS.Tables["Product"].Clear();
da.Fill(DS, "Product");
dgvProduct.DataSource = DS.Tables["Product"];
}
}
如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答?。?點擊進入論壇