我在这个问题上苦苦挣扎了几天,我自己无法修复它。
我有3个datagridviews
字母表包含一列仅包含字符,例如'a','b'和'c'
State包含三列:'Name'; '是开始状态','是结束状态'。第一个是字符串列。另外两个是复选框列。
Transition包含三列。从(组合框),到(组合框),符号(组合框)
我的目标是使用用户在州和国家/地区输入的数据。我的组合框的字母表。
例如: 用户在字母表中输入以下数据:'a'和'b' 用户在状态下输入以下数据:
当用户想要填充转换时,他们可以选择列“从”和“到”以下选项:LR_0; LR_1或LR_2。对于符号,他们可以使用'a'或'b'。
现在是棘手的部分。当用户将LR_0重命名为LR_3时,组合框也需要更新。当用户删除LR_0行时,包含LR_0的转换中的行也需要删除。
我已经使用了很多可能性,但没有一个能正常工作。
选项1 使用实习列表并将绑定绑定到组合框,每次添加行时我也将其添加到列表中。删除行时,我也会从列表中删除它,并删除包含该值的转换中的每一行。
问题:有时会更改值以及添加值时。改变组合框中的值也很困难
选项2 使用iList接口并使用下面的datagridview信息创建一个枚举器.Rows.Count = length和.Rows [0] .Cells [0] .Value = value。
问题:当信息发生变化时。组合框未更新
选项3 使用与选项2相同设置的iBindingList接口。这几乎是正确的。当我删除或添加内容时,列表会更改。唯一的问题是组合框在更改特定行时不会更改其值。
我此刻此刻。 DataTableColumnSource
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Gui
{
public class DataTableColumnSource<T> : IBindingList
{
public event ListChangedEventHandler ListChanged;
public DataGridView dataTable { get; set; }
public int column { get; set; }
public DataTableColumnSource(ref DataGridView dataTable, int column)
{
this.dataTable = dataTable;
this.column = column;
}
public void PosibleChange(ListChangedType type, int index)
{
if (ListChanged != null)
{
ListChanged(this, new ListChangedEventArgs(type, index));
}
}
public void AddIndex(PropertyDescriptor property)
{
throw new NotImplementedException();
}
public object AddNew()
{
return new Comboboxitem<T>(default(T), -1); ;
}
public bool AllowEdit
{
get { throw new NotImplementedException(); }
}
public bool AllowNew
{
get { return true; }
}
public bool AllowRemove
{
get { throw new NotImplementedException(); }
}
public void ApplySort(PropertyDescriptor property, ListSortDirection direction)
{
throw new NotImplementedException();
}
public int Find(PropertyDescriptor property, object key)
{
throw new NotImplementedException();
}
public bool IsSorted
{
get { throw new NotImplementedException(); }
}
public void RemoveIndex(PropertyDescriptor property)
{
throw new NotImplementedException();
}
public void RemoveSort()
{
throw new NotImplementedException();
}
public ListSortDirection SortDirection
{
get { throw new NotImplementedException(); }
}
public PropertyDescriptor SortProperty
{
get { throw new NotImplementedException(); }
}
public bool SupportsChangeNotification
{
get { return true; }
}
public bool SupportsSearching
{
get { return false; }
}
public bool SupportsSorting
{
get { return false; }
}
public int Add(object value)
{
throw new NotImplementedException();
}
public void Clear()
{
throw new NotImplementedException();
}
public bool Contains(object value)
{
throw new NotImplementedException();
}
public int IndexOf(object value)
{
throw new NotImplementedException();
}
public void Insert(int index, object value)
{
throw new NotImplementedException();
}
public bool IsFixedSize
{
get { throw new NotImplementedException(); }
}
public bool IsReadOnly
{
get { throw new NotImplementedException(); }
}
public void Remove(object value)
{
throw new NotImplementedException();
}
public void RemoveAt(int index)
{
throw new NotImplementedException();
}
public object this[int index]
{
get
{
if (this.dataTable.Rows[index].Cells[this.column].Value == null)
return null;
T w =(T) Convert.ChangeType(this.dataTable.Rows[index].Cells[this.column].Value, typeof(T));
return w;
}
set
{
throw new NotImplementedException();
}
}
public void CopyTo(Array array, int index)
{
throw new NotImplementedException();
}
public int Count
{
get
{
return this.dataTable.Rows.Count -1;
}
}
public bool IsSynchronized
{
get { throw new NotImplementedException(); }
}
public object SyncRoot
{
get { throw new NotImplementedException(); }
}
public System.Collections.IEnumerator GetEnumerator()
{
int c = Count;
for (int i = 0; i < c; i++)
yield return this[i];
}
}
}
GUI
public partial class FrmNDFA : Form
{
DataTableColumnSource<char> alphabetSource;
DataTableColumnSource<string> stateSource;
int lastDeletedIndex;
public FrmNDFA()
{
InitializeComponent();
alphabetSource = new DataTableColumnSource<char>(ref this.dgvAlphabet, 0);
stateSource = new DataTableColumnSource<string>(ref this.dgvStates, 0);
DataGridViewComboBoxColumn column = (DataGridViewComboBoxColumn)this.dgvTransitions.Columns[0];
BindingSource clm1BS = new BindingSource();
clm1BS.DataSource = stateSource;
column.DataSource = clm1BS;
column.ValueType = typeof(string);
column = (DataGridViewComboBoxColumn)this.dgvTransitions.Columns[1];
BindingSource clm2BS = new BindingSource();
clm2BS.DataSource = stateSource;
column.DataSource = clm2BS;
column.ValueType = typeof(string);
column = (DataGridViewComboBoxColumn)this.dgvTransitions.Columns[2];
BindingSource clm3BS = new BindingSource();
clm3BS.DataSource = alphabetSource;
column.DataSource = clm3BS;
column.ValueType = typeof(char);
}
private void dgvAlphabet_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
lastDeletedIndex = e.Row.Index;
}
private void dgvAlphabet_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
{
DataGridViewRow row = e.Row;
string value = (row.Cells[0].Value != null)? row.Cells[0].Value.ToString() : "";
alphabetSource.PosibleChange(ListChangedType.ItemDeleted, lastDeletedIndex);
List<DataGridViewRow> removeRows = new List<DataGridViewRow>();
//Update transitions
foreach (DataGridViewRow dataRow in this.dgvTransitions.Rows)
{
if (dataRow.Cells[2].Value != null && dataRow.Cells[2].Value.ToString().Equals(value))
removeRows.Add(dataRow);
}
foreach(DataGridViewRow dataRow in removeRows)
{
this.dgvTransitions.Rows.Remove(dataRow);
}
}
private void dgvAlphabet_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if(this.dgvAlphabet.Rows[e.RowIndex].IsNewRow)
alphabetSource.PosibleChange(ListChangedType.ItemAdded, e.RowIndex);
else
alphabetSource.PosibleChange(ListChangedType.ItemChanged, e.RowIndex);
}
private void dgvAlphabet_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
e.Cancel = e.FormattedValue != null && e.FormattedValue.ToString().Length > 1;
}
private void dgvStates_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
lastDeletedIndex = e.Row.Index;
}
private void dgvStates_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
{
DataGridViewRow row = e.Row;
string value = (row.Cells[0].Value != null) ? row.Cells[0].Value.ToString() : "";
stateSource.PosibleChange(ListChangedType.ItemDeleted, this.dgvStates.Rows.IndexOf(e.Row));
List<DataGridViewRow> removeRows = new List<DataGridViewRow>();
//Update transitions
foreach (DataGridViewRow dataRow in this.dgvTransitions.Rows)
{
if (dataRow.Cells[0].Value != null && dataRow.Cells[0].Value.Equals(value))
removeRows.Add(dataRow);
else if (dataRow.Cells[1].Value != null && dataRow.Cells[1].Value.Equals(value))
removeRows.Add(dataRow);
}
foreach(DataGridViewRow dataRow in removeRows)
{
this.dgvTransitions.Rows.Remove(dataRow);
}
}
private void dgvStates_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex != 0)
return;
stateSource.PosibleChange(ListChangedType.ItemChanged, e.RowIndex);
}
}