C# 将DataGridViewComboxColumn绑定到DataGridView列

C# 将DataGridViewComboxColumn绑定到DataGridView列,c#,winforms,datagridview,datagridviewcombobox,C#,Winforms,Datagridview,Datagridviewcombobox,我为这个问题挣扎了几天,但我自己无法解决它 我有3个DataGridView 字母表 陈述 过渡 字母表包含一列,仅包含字符,例如“a”、“b”和“c” 状态包含三列:“名称”;“是“开始状态”和“结束状态”。第一个是字符串列。另外两个是复选框列 转换包含三列。从(组合框),到(组合框),符号(组合框) 我的目标是使用用户在状态和字母表中为我的组合框输入的数据 例如: 用户在字母表中输入以下数据:“a”和“b” 用户在状态中输入以下数据: LR_0;是启动状态;没有终结状态 LR_1;没有

我为这个问题挣扎了几天,但我自己无法解决它

我有3个DataGridView

  • 字母表
  • 陈述
  • 过渡
字母表包含一列,仅包含字符,例如“a”、“b”和“c”

状态包含三列:“名称”;“是“开始状态”和“结束状态”。第一个是字符串列。另外两个是复选框列

转换包含三列。从(组合框),到(组合框),符号(组合框)

我的目标是使用用户在状态和字母表中为我的组合框输入的数据

例如: 用户在字母表中输入以下数据:“a”和“b” 用户在状态中输入以下数据:

  • LR_0;是启动状态;没有终结状态
  • LR_1;没有启动状态;没有终结状态
  • LR_2;没有启动状态;这是最终状态
当用户想要填充过渡时,他们可以为列“从”和“到”反折叠选项选择:LR_0;LR_1或LR_2。对于符号,他们可以使用“a”或“b”

现在是棘手的部分。当用户将LR_0重命名为LR_3时,组合框也需要更新。当用户删除LR_0行时,转换中包含LR_0的行也需要删除

我使用了很多可能性,但是没有一个是100%正确的

选项1 使用实习生列表并将其绑定到组合框,每次添加一行时,我也会将其添加到列表中。当删除一行时,我也会将其从列表中删除,并删除转换中包含该值的每一行

问题:当某个值被更改或添加时,有时是未知的。更改组合框中的值也很困难

选项2 使用iList接口并使用以下datagridview信息生成枚举数。Rows.Count=length和.Rows[0]。Cells[0]。Value=Value

问题:当信息发生更改时。组合框未更新

选项3 使用与选项2相同设置的iBindingList界面。这几乎是正确的。当我删除或添加某些内容时,列表会更改。唯一的问题是,当特定行更改时,组合框不会更改其值

我现在有这个。 DataTableColumnSource

使用系统;
使用系统组件模型;
使用System.Windows.Forms;
名称空间Gui
{
公共类DataTableColumnSource:IBindingList
{
公共事件列表更改事件处理程序列表更改;
公共DataGridView数据表{get;set;}
公共int列{get;set;}
公共DataTableColumnSource(参考DataGridView dataTable,int列)
{
this.dataTable=dataTable;
this.column=列;
}
public void PosibleChange(ListChangedType类型,int索引)
{
如果(ListChanged!=null)
{
ListChanged(这个,新的ListChangedEventArgs(类型,索引));
}
}
公共void AddIndex(PropertyDescriptor属性)
{
抛出新的NotImplementedException();
}
公共对象AddNew()
{
返回新的Comboboxitem(默认值为-1);
}
公众允许
{
获取{抛出新的NotImplementedException();}
}
公共场所许可
{
获取{return true;}
}
公共布尔允许移动
{
获取{抛出新的NotImplementedException();}
}
public void ApplySort(PropertyDescriptor属性,ListSortDirection方向)
{
抛出新的NotImplementedException();
}
public int Find(PropertyDescriptor属性,对象键)
{
抛出新的NotImplementedException();
}
公共图书馆分类
{
获取{抛出新的NotImplementedException();}
}
public void RemoveIndex(PropertyDescriptor属性)
{
抛出新的NotImplementedException();
}
public void RemoveSort()
{
抛出新的NotImplementedException();
}
公共列表排序定向排序定向
{
获取{抛出新的NotImplementedException();}
}
公共属性描述符SortProperty
{
获取{抛出新的NotImplementedException();}
}
公共图书馆支持通告
{
获取{return true;}
}
公共事业支持研究
{
获取{return false;}
}
公共图书馆
{
获取{return false;}
}
公共整数加法(对象值)
{
抛出新的NotImplementedException();
}
公共空间清除()
{
抛出新的NotImplementedException();
}
公共布尔包含(对象值)
{
抛出新的NotImplementedException();
}
public int IndexOf(对象值)
{
抛出新的NotImplementedException();
}
公共void插入(int索引,对象值)
{
抛出新的NotImplementedException();
}
公共图书馆是固定大小的
{
获取{抛出新的NotImplementedException();}
}
公共图书馆是只读的
{
获取{抛出新的NotImplementedException();}
}
公共无效删除(对象值)
{
抛出新的NotImplementedException();
}
公共无效删除(整数索引)
{
抛出新的NotImplementedException();
}
公共对象此[int索引]
{
得到
{
if(this.dataTable.Rows[index].Cells[this.column].Value==null)
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];
        }
    }
}
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);

        }
    }