排序组合框并重新分配数据源
本文关键字:分配 数据源 新分配 组合 排序 | 更新日期: 2023-09-27 18:25:34
背景:有两个组合框,它们的区别仅在于Sorted属性。comboBox1的Sorted属性设置为true,comboBox2的Sorted特性设置为false。当试图重新分配/重置这两个组合框的数据源属性时,comboBox1不显示数据,comboBox2显示数据。为什么Sorted属性阻止comboBox1正确显示其"数据"?
下面包含的所有代码:
public partial class Form1 : Form
{
private string[] a8BitGames = { "Metroid", "Zelda", "Phantasy Star", "SB:S&SEP" };
private string[] a16BitGames = { "StarFox", "Link", "Final Fantasy", "Altered Beast" };
private List<string> lSomeList = null;
private List<string> lSomeOtherList = null;
public Form1()
{
InitializeComponent();
this.lSomeList = new List<string>(a8BitGames);
this.lSomeOtherList = new List<string>(a16BitGames);
this.comboBox1.DataSource = lSomeList;
this.comboBox2.DataSource = lSomeOtherList;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
this.IndexChanged(1);
}
private void IndexChanged(int comboBox)
{
this.comboBox1.DataSource = null;
this.comboBox1.DataSource = a16BitGames;
this.comboBox2.DataSource = null;
this.comboBox2.DataSource = a8BitGames;
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
this.IndexChanged(2);
}
}
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.comboBox1 = new System.Windows.Forms.ComboBox();
this.comboBox2 = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// comboBox1
//
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Location = new System.Drawing.Point(13, 13);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(121, 21);
this.comboBox1.Sorted = true;
this.comboBox1.TabIndex = 0;
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
//
// comboBox2
//
this.comboBox2.FormattingEnabled = true;
this.comboBox2.Location = new System.Drawing.Point(13, 41);
this.comboBox2.Name = "comboBox2";
this.comboBox2.Size = new System.Drawing.Size(121, 21);
this.comboBox2.TabIndex = 1;
this.comboBox2.SelectedIndexChanged += new System.EventHandler(this.comboBox2_SelectedIndexChanged);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 262);
this.Controls.Add(this.comboBox2);
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.ComboBox comboBox2;
}
是否意外隐藏了异常?根据MSDN,当"试图对连接到数据源的组合框进行排序"时,您将收到一个"ArgumentException"
http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.sorted.aspx
尝试在设置DataSource 时对列表进行排序
public List<string> A16Games
{
get { return this.a16BitGames.OrderBy(x => x).ToList(); }
}
public List<string> A8Games
{
get { return this.a8BitGames.OrderBy(x => x).ToList(); }
}
this.comboBox1.DataSource = this.A16Games;
this.comboBox2.DataSource = this.A8Games;
问题是无法更改排序组合框的数据源。以下是ComboBox控件的代码摘录:
protected override void OnDataSourceChanged(EventArgs e)
{
if ((this.Sorted && (this.DataSource != null)) && base.Created)
{
this.DataSource = null;
throw new InvalidOperationException(System.Windows.Forms.SR.GetString("ComboBoxDataSourceWithSort"));
}
...
...
}
在这种情况下,您应该收到InvalidOperationException。为什么你没有收到?答案是:
ComboBox控件中DataSource属性的实现重定向到其基类(ListControl)实现:
public object DataSource
{
get
{
return base.DataSource;
}
set
{
base.DataSource = value;
}
}
然后在基类的DataSource:中
public object DataSource
{
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
get
{
return this.dataSource;
}
set
{
if (((value != null) && !(value is IList)) && !(value is IListSource))
{
throw new ArgumentException(System.Windows.Forms.SR.GetString("BadDataSourceForComplexBinding"));
}
if (this.dataSource != value)
{
try
{
this.SetDataConnection(value, this.displayMember, false);
}
catch
{
this.DisplayMember = "";
}
if (value == null)
{
this.DisplayMember = "";
}
}
}
}
请注意无声的catch块。由于SetDataConnection调用OnDataSourceChanged,所以就我的分析而言,这就是原因。如果我错了,请纠正我。