IBindingList
をサポートする必要がある自分のコレクションを実装するのに特に問題があります。IBindingListを使用したWinFormsでのデータバインディングが空のリストで失敗する
特定のデータクラス(DataItem
)のコレクションクラス(DataCollection
)があります。コレクションは、IBindingList
,IList
、IList<DataItem>
、DataItem
の各インターフェイスを実装しています。INotifyPropertyChanged
(データバインディングにはパブリックプロパティを持ちます)。
私は、グリッドのDataSource
プロパティを設定することにより、DataGridView
にコレクションをバインドしようとすると、それが正しくかのコレクションは結合の瞬間に空ではありません動作します。そうでない場合、コレクションが空の場合、グリッドは行(つまり、DataItems
)がコレクションに追加または削除されたときにセルが空のままであることに気づきます。問題は、AutoGenerateColumns=true
の場合、グリッドがデータクラスのパブリックメンバーを認識できず、列を生成できないことです。
私が試したことは、BindingList<DataItem>
を使用してDataItems
をバインドします。その場合、グリッドは、DataSource
の設定時にリストが空であっても正しく動作します。一方、BindingList<object>
(内容は同じDataItems
)を使用した場合、動作は私のDataCollection
と同じように間違っています。私は問題は、バインディングの瞬間にリストが空であれば、データバインディングがDataItem
タイプを正しく検出できず、最終的にアイテムがコレクションに追加されたときに後で回復できないということです。
重要なのは、コレクションがバインディング時に空でない場合に機能することです。私は列を指定するときに、同じエラーが発生することを
お知らせ:
this.dataGridView.ReadOnly = true;
this.dataGridView.AutoGenerateColumns = false;
DataGridViewTextBoxColumn column;
column = new DataGridViewTextBoxColumn();
column.DataPropertyName = "Id";
column.HeaderText = "Id";
this.dataGridView.Columns.Add(column);
column = new DataGridViewTextBoxColumn();
column.DataPropertyName = "UserName";
column.HeaderText = "UserName";
this.dataGridView.Columns.Add(column);
this.dataGridView.DataSource = myList;
私もIBindingList
のAllowNew
にtrue
を返すようにしようとしました。それには目に見える影響はなかった。また、失敗した何
は以下の通りです:
var bindingSource = new BindingSource();
bindingSource.DataSource = myList;
this.dataGridView.DataSource = bindingSource;
、どのように私は私のDataItems
を認識するための結合メカニズムを伝えることができている質問?リストの種類は、それが正常に動作するBindingList<DataItem>
ある場合
public partial class Form1: Form {
public Form1() {
InitializeComponent();
}
class DataItem: INotifyPropertyChanged {
private int _id;
public int Id {
get {
return _id;
}
set {
if (value != _id) {
_id = value;
OnPropertyChanged("Id");
}
}
}
private string _userName;
public string UserName {
get {
return _userName;
}
set {
if (value != _userName) {
_userName = value;
OnPropertyChanged("UserName");
}
}
}
private void OnPropertyChanged(string propertyName) {
var handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
/// Make a list of type DataItem or object...
//BindingList<object> list = new BindingList<object>() {
BindingList<DataItem> list = new BindingList<DataItem>() {
//new DataItem() {
// Id = 1,
// UserName = "testuser"
//}
};
private void Form1_Load(object sender, EventArgs e) {
DataGridView dataGridView = new System.Windows.Forms.DataGridView();
dataGridView.Size = new Size(this.Width-20, this.Height-30);
dataGridView.AutoGenerateColumns = true;
DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn();
column.DataPropertyName = "Id";
column.HeaderText = "Id";
dataGridView.Columns.Add(column);
this.Controls.Add(dataGridView);
dataGridView.DataSource = list;
list.Add(
new DataItem() {
Id = 3,
UserName = "admin"
}
);
// Make some modifications on the data...
(new System.Threading.Thread(state => {
System.Threading.Thread.CurrentThread.IsBackground = true;
System.Threading.Thread.Sleep(2000);
this.Invoke((Action)(() => {
list.Add(new DataItem() {
Id = 2,
UserName = "guest"
});
}));
System.Threading.Thread.Sleep(2000);
this.Invoke((Action)(() => {
DataItem user = (list.First(obj => ((DataItem)obj).Id == 3)) as DataItem;
user.UserName = "Administrator";
}));
})).Start();
}
}
:私は問題を示して小さなテストプロジェクトを作っ
:
は
UPDATE 1を(ありがとうございます)。タイプがBindingList<object>
の場合は、DataSource
を初期化するときにリストが空でない場合にのみ機能します。
解決策は非常に簡単で、私はそれをインターネットで検索することができませんでした。どうもありがとうございました!! – thaller