我通過在Windows窗體應用程序中擴展DataGridView來創建自定義網格控件。我使用一些自定義函數來設置列只讀和一些其他功能。我目前的問題是,當我使用同一種形式的多個控件時,它只反映了上次控件的函數執行輸出。如何使每個控件成爲用戶控件的單獨實例?C#Windows窗體用戶控件
public partial class dGridView : DataGridView
{
#region Member variables
DatagridViewCheckBoxHeaderCell chkHeader;
bool NeedToPopulateColumns = true;
public event DatagridViewCellButtonClickedHandler CellButtonClicked;
private int currentComboSelIndex;
#endregion
public dGridView()
{
InitializeComponent();
if (!DesignMode)
{
this.DoubleBuffered = true;
this.AutoGenerateColumns = false;
this.CellButtonClicked += new DatagridViewCellButtonClickedHandler(dGridView_CellButtonClicked);
}
}
#region Properties
/// <summary>
/// Gets or sets the datasource used to define columns.
/// </summary>
public object DesignDataSource
{
get;
set;
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool ExtendLastColumn
{
get;
set;
}
private List<string> AutoFilterColumnNames
{
get;
set;
}
private List<string> HiddenColumnsList
{
get;
set;
}
private List<string> ReadOnlyColumnsList
{
get;
set;
}
private List<string> ButtonColumnsList
{
get;
set;
}
private List<DGVSupportClass.ComboBoxColumns> ComboBoxColumnsList
{
get;
set;
}
private List<CustomCaptions> customCaptionList
{
get;
set;
}
#endregion
#region Methods
#region Public Methods
public void AddFilterToColumns(List<string> columnNames)
{
if (columnNames.Count > 0)
{
this.AutoFilterColumnNames = columnNames;
}
}
public void HiddenColumns(List<string> columnNames)
{
if (columnNames.Count > 0)
{
this.HiddenColumnsList = columnNames;
HideColumnsInList(this.HiddenColumnsList);
}
}
public void ReadOnlyColumns(List<string> columnNames)
{
if (columnNames.Count > 0)
{
this.ReadOnlyColumnsList = columnNames;
ReadOnlyColumnsInList(this.ReadOnlyColumnsList);
}
}
public void ReadOnlyRow(int rowIndex)
{
if (this.DataSource == null)
{
return;
}
this.Rows[rowIndex].ReadOnly = true;
}
public void AddButtonToCells(List<string> columnNames)
{
this.ButtonColumnsList = columnNames;
NeedToPopulateColumns = true;
FindBindingDataObjectType();
}
public void AddComboBoxColumn(List<DGVSupportClass.ComboBoxColumns> comboBoxColumns)
{
this.ComboBoxColumnsList = comboBoxColumns;
NeedToPopulateColumns = true;
FindBindingDataObjectType();
}
public void SetCustomDataSourceToComboBoxCell(int colIndex, int rowIndex, object cboxDataSource, string displayMember, string valueMember)
{
if (this.Columns[colIndex].GetType() != typeof(DataGridViewComboBoxColumn))
{
throw new Exception(string.Format("Column [{0}] is not a DataGridViewComboBoxColumn", colIndex));
}
if (string.IsNullOrEmpty(displayMember) || string.IsNullOrEmpty(valueMember))
{
throw new Exception("Display and Value Member must be passed");
}
DataGridViewComboBoxCell combo = this[colIndex, rowIndex] as DataGridViewComboBoxCell;
combo.DataSource = cboxDataSource;
combo.DisplayMember = displayMember;
combo.ValueMember = valueMember;
}
public void SetCustomDataSourceToComboBoxCell(int colIndex, int rowIndex, string[] cboxDataSource)
{
if (this.Columns[colIndex].GetType() != typeof(DataGridViewComboBoxColumn))
{
throw new Exception(string.Format("Column [{0}] is not a DataGridViewComboBoxColumn", colIndex));
}
DataGridViewComboBoxCell combo = this[colIndex, rowIndex] as DataGridViewComboBoxCell;
combo.DataSource = cboxDataSource;
}
public void CustomColumnCaptions(List<CustomCaptions> newColumnCaptions)
{
if (newColumnCaptions == null || newColumnCaptions.GetType() == typeof(System.DBNull))
{
return;
}
if (this.customCaptionList != newColumnCaptions)
this.customCaptionList = newColumnCaptions;
foreach (CustomCaptions col in newColumnCaptions)
{
if (this.Columns[col.ColumnName] != null)
this.Columns[col.ColumnName].HeaderCell.Value = col.ColumnCaption;
}
}
public void SetCustomColumnCaption(string columnName, string newCaption)
{
if (this.Columns.Contains(columnName))
{
if (this.Columns[columnName] != null)
this.Columns[columnName].HeaderCell.Value = newCaption;
}
CustomCaptions cap = new CustomCaptions(columnName, newCaption);
if (!customCaptionList.Contains(cap))
{
customCaptionList.Add(cap);
}
}
#endregion
#region Private Methods
private void AddFilterToColumnsInList(List<string> columnNames)
{
if (this.DataSource == null || columnNames == null)
{
return;
}
foreach (DataGridViewColumn col in this.Columns)
{
if (col.GetType() == typeof(DataGridViewTextBoxColumn) && columnNames.Contains(col.Name))
col.HeaderCell = new
DataGridViewAutoFilter.DataGridViewAutoFilterColumnHeaderCell(col.HeaderCell);
}
}
private void HideColumnsInList(List<string> columnNames)
{
if (this.DataSource == null || columnNames == null)
{
return;
}
foreach (DataGridViewColumn col in this.Columns)
{
if (this.HiddenColumnsList.Contains(col.Name))
{
col.Visible = false;
}
}
}
/// <summary>
/// Finds the type of the binding data object.
/// </summary>
private void FindBindingDataObjectType()
{
this.SuspendLayout();
this.ScrollBars = ScrollBars.None;
if (NeedToPopulateColumns)
{
if (this.DataSource is System.Collections.IList && this.DataSource.GetType().IsGenericType)
{
PopulateDataGridColumnsFromICartItem();
}
else
{
PopulateDataGridColumnsFromDataView();
}
NeedToPopulateColumns = false;
if (this.customCaptionList != null && this.customCaptionList.GetType() != typeof(System.DBNull))
{
CustomColumnCaptions(this.customCaptionList);
}
}
this.ScrollBars = ScrollBars.Both;
this.ResumeLayout();
}
/// <summary>
/// Populates the DataGridView columns with controls according to the
/// DataType of each columns which it represents. e.g. when a boolean
/// value found, then a DataGridViewCheckBoxColumn will be added and
/// for datetime it will be ESCalendarColumn (a custom control).
/// </summary>
private void PopulateDataGridColumnsFromDataView()
{
bool isComboAdded = false;
DataTable dt = null;
if (null == this.DataSource)
{
return;
}
else
{
switch (this.DataSource.GetType().ToString())
{
case "System.Data.DataTable":
dt = (DataTable)this.DataSource;
break;
case "System.Data.DataView":
dt = ((DataView)this.DataSource).Table;
break;
case "System.Data.DataSet":
dt = ((DataSet)this.DataSource).Tables[0];
break;
case "System.Windows.Forms.BindingSource":
if (((BindingSource)this.DataSource).DataSource.GetType() == typeof(DataTable))
{
dt = (DataTable)((BindingSource)this.DataSource).DataSource;
}
break;
default:
return;
}
}
this.Columns.Clear();
foreach (DataColumn dc in dt.Columns)
{
if (ButtonColumnsList != null && ButtonColumnsList.Contains(dc.ColumnName))
{
DataGridViewButtonColumn dvButton = new DataGridViewButtonColumn();
dvButton.Name = dc.ColumnName;
dvButton.HeaderText = dc.ColumnName;
this.Columns.Add(dvButton);
this.Columns[dvButton.Name].DataPropertyName = dvButton.Name;
continue;
}
if (ComboBoxColumnsList != null && ComboBoxColumnsList.Count > 0)
{
foreach (DGVSupportClass.ComboBoxColumns tmpData in ComboBoxColumnsList)
{
if (tmpData.ColumnName == dc.ColumnName)
{
DataGridViewComboBoxColumn comboCol = new DataGridViewComboBoxColumn();
comboCol.DataPropertyName = dc.ColumnName;
comboCol.Name = dc.ColumnName;
comboCol.HeaderText = dc.ColumnName;
comboCol.DataSource = tmpData.DataSource;
if (!string.IsNullOrEmpty(tmpData.Display))
{
comboCol.DisplayMember = tmpData.Display;
comboCol.ValueMember = tmpData.Value;
}
comboCol.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton;
comboCol.FlatStyle = FlatStyle.Standard;
this.Columns.Add(comboCol);
isComboAdded = true;
break;
}
}
}
if (isComboAdded)
{
isComboAdded = false;
continue;
}
switch (((DataColumn)dc).DataType.ToString())
{
case "System.String":
case "System.Int32":
case "System.Int64":
case "System.Decimal":
case "System.Guid":
this.Columns.Add(dc.ColumnName, dc.Caption);
this.Columns[dc.ColumnName].DataPropertyName = dc.ColumnName;
this.Columns[dc.ColumnName].SortMode = DataGridViewColumnSortMode.Automatic;
break;
case "System.Boolean":
DataGridViewCheckBoxColumn chkbox = new DataGridViewCheckBoxColumn();
chkHeader = new DatagridViewCheckBoxHeaderCell();
chkbox.HeaderCell = chkHeader;
chkbox.Name = "chkBox" + dc.ColumnName;
chkbox.HeaderText = dc.ColumnName;
chkHeader.OnCheckBoxClicked += new CheckBoxClickedHandler(chkHeader_OnCheckBoxClicked);
this.Columns.Add(chkbox);
this.Columns[chkbox.Name].DataPropertyName = dc.ColumnName;
this.Columns[chkbox.Name].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
this.Columns[chkbox.Name].SortMode = DataGridViewColumnSortMode.NotSortable;
break;
case "System.DateTime":
ESCalendarColumn calendarCol = new ESCalendarColumn();
calendarCol.Name = ((DataColumn)dc).ColumnName;
calendarCol.HeaderText = ((DataColumn)dc).Caption;
this.Columns.Add(calendarCol);
this.Columns[calendarCol.Name].DataPropertyName = calendarCol.Name;
this.Columns[calendarCol.Name].SortMode = DataGridViewColumnSortMode.Automatic;
break;
default:
if (((DataColumn)dc).DataType.IsEnum)
{
List<DGVSupportClass.EnumToComboClass> lstCbo = new List<DGVSupportClass.EnumToComboClass>();
DataGridViewComboBoxColumn comboCol = new DataGridViewComboBoxColumn();
comboCol.DataPropertyName = ((DataColumn)dc).ColumnName;
comboCol.Name = ((DataColumn)dc).ColumnName;
comboCol.HeaderText = ((DataColumn)dc).Caption;
comboCol.DataSource = Enum.GetValues(dc.DataType);
comboCol.FlatStyle = FlatStyle.Standard;
if (((DataColumn)dc).ReadOnly) comboCol.ReadOnly = true;
this.Columns.Add(comboCol);
}
else
{
this.Columns.Add(dc.ColumnName, dc.Caption);
this.Columns[dc.ColumnName].DataPropertyName = dc.ColumnName;
this.Columns[dc.ColumnName].SortMode = DataGridViewColumnSortMode.Automatic;
}
break;
}
}
NeedToPopulateColumns = false;
AddFilterToColumnsInList(this.AutoFilterColumnNames);
HideColumnsInList(this.HiddenColumnsList);
// Extend the last column
if (this.ExtendLastColumn)
{
this.Columns[this.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
}
/// <summary>
/// Populates the DataGridView columns with controls according to the
/// DataType of each columns which it represents. e.g. when a boolean
/// value found, then a DataGridViewCheckBoxColumn will be added and
/// for datetime it will be ESCalendarColumn (a custom control).
/// </summary>
private void PopulateDataGridColumnsFromICartItem()
{
this.Columns.Clear();
System.Reflection.PropertyInfo[] propertyInfos = null;
bool isComboAdded = false;
if (this.DesignDataSource != null)
{
if (this.DesignDataSource != null && this.DesignDataSource is System.Collections.IList && this.DesignDataSource.GetType().IsGenericType)
{
if (((System.Collections.IList)this.DesignDataSource).Count > 0 && (((System.Collections.IList)this.DesignDataSource)[0]) != null)
{
propertyInfos = (((System.Collections.IList)this.DesignDataSource)[0]).GetType().GetProperties();
}
else
{
propertyInfos = this.DesignDataSource.GetType().GetProperties();
propertyInfos = propertyInfos[propertyInfos.Length - 1].PropertyType.GetProperties();
}
}
}
else
{
if (this.DataSource != null && this.DataSource is System.Collections.IList && this.DataSource.GetType().IsGenericType)
{
if (((System.Collections.IList)this.DataSource).Count > 0)
{
propertyInfos = (((System.Collections.IList)this.DataSource)[0]).GetType().GetProperties();
}
else
{
propertyInfos = this.DataSource.GetType().GetProperties();
propertyInfos = propertyInfos[propertyInfos.Length - 1].PropertyType.GetProperties();
}
}
}
if (propertyInfos != null)
{
foreach (var item in propertyInfos)
{
if (ComboBoxColumnsList != null && ComboBoxColumnsList.Count > 0)
{
foreach (DGVSupportClass.ComboBoxColumns tmpData in ComboBoxColumnsList)
{
if (tmpData.ColumnName == item.Name)
{
DataGridViewComboBoxColumn comboCol = new DataGridViewComboBoxColumn();
comboCol.DataPropertyName = item.Name;
comboCol.Name = item.Name;
comboCol.HeaderText = item.Name;
comboCol.DataSource = tmpData.DataSource;
if (!string.IsNullOrEmpty(tmpData.Display))
{
comboCol.DisplayMember = tmpData.Display;
comboCol.ValueMember = tmpData.Value;
}
comboCol.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton;
comboCol.FlatStyle = FlatStyle.Standard;
this.Columns.Add(comboCol);
isComboAdded = true;
break;
}
}
}
if (isComboAdded)
{
isComboAdded = false;
continue;
}
if (ButtonColumnsList != null && ButtonColumnsList.Contains(item.Name))
{
DataGridViewButtonColumn dvButton = new DataGridViewButtonColumn();
dvButton.Name = item.Name;
dvButton.HeaderText = item.Name;
this.Columns.Add(dvButton);
this.Columns[dvButton.Name].DataPropertyName = dvButton.Name;
}
else
{
switch (item.PropertyType.ToString())
{
case "System.String":
case "System.Int32":
case "System.Int64":
case "System.Decimal":
case "System.Guid":
DataGridViewTextBoxColumn txtBox = new DataGridViewTextBoxColumn();
txtBox.Name = item.Name;
this.Columns.Add(txtBox);
this.Columns[item.Name].DataPropertyName = item.Name;
break;
case "System.Boolean":
DataGridViewCheckBoxColumn chkbox = new DataGridViewCheckBoxColumn();
chkHeader = new DatagridViewCheckBoxHeaderCell();
chkbox.HeaderCell = chkHeader;
chkbox.Name = "chkBox" + item.Name;
chkbox.HeaderText = item.Name;
chkHeader.OnCheckBoxClicked += new CheckBoxClickedHandler(chkHeader_OnCheckBoxClicked);
this.Columns.Add(chkbox);
this.Columns[chkbox.Name].DataPropertyName = item.Name;
this.Columns[chkbox.Name].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
this.Columns[chkbox.Name].SortMode = DataGridViewColumnSortMode.NotSortable;
break;
case "System.DateTime":
ESCalendarColumn calendarCol = new ESCalendarColumn();
calendarCol.Name = item.Name;
calendarCol.HeaderText = item.Name;
this.Columns.Add(calendarCol);
this.Columns[calendarCol.Name].DataPropertyName = calendarCol.Name;
break;
default:
if (item.PropertyType.IsEnum && item.PropertyType.IsPublic)
{
List<DGVSupportClass.EnumToComboClass> lstCbo = new List<DGVSupportClass.EnumToComboClass>();
foreach (System.Reflection.FieldInfo fInfo in item.PropertyType.GetFields(
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static))
{
lstCbo.Add(new DGVSupportClass.EnumToComboClass(fInfo.Name, fInfo.GetRawConstantValue().ToString()));
}
DataGridViewComboBoxColumn comboCol = new DataGridViewComboBoxColumn();
comboCol.DataPropertyName = item.Name;
comboCol.Name = item.Name;
comboCol.HeaderText = item.Name;
comboCol.DataSource = lstCbo;
comboCol.DisplayMember = "Display";
comboCol.ValueMember = "Value";
comboCol.FlatStyle = FlatStyle.Standard;
this.Columns.Add(comboCol);
}
else if (!item.PropertyType.IsAbstract)
{
DataGridViewTextBoxColumn txtBoxDefault = new DataGridViewTextBoxColumn();
txtBoxDefault.Name = item.Name;
txtBoxDefault.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
this.Columns.Add(txtBoxDefault);
this.Columns[item.Name].DataPropertyName = item.Name;
}
break;
}
}
}
}
if (this.ExtendLastColumn)
{
this.Columns[this.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
AddFilterToColumnsInList(this.AutoFilterColumnNames);
HideColumnsInList(this.HiddenColumnsList);
}
#endregion
#endregion
#region Events
protected override void OnDataSourceChanged(EventArgs e)
{
if (this.DesignDataSource == null)
{
this.DesignDataSource = this.DataSource;
NeedToPopulateColumns = true;
}
FindBindingDataObjectType();
base.OnDataSourceChanged(e);
}
protected override void OnCellContentClick(DataGridViewCellEventArgs e)
{
if (this.Columns[e.ColumnIndex].GetType() == typeof(DataGridViewButtonColumn))
{
DatagridViewCellButtonClickEventArgs dc = new DatagridViewCellButtonClickEventArgs(this.CurrentCell.Value.ToString(),
this.CurrentCell.Tag, this.CurrentCell.ColumnIndex, this.CurrentCell.RowIndex, this.CurrentCell.Value);
if (CellButtonClicked != null) { CellButtonClicked(this, dc); }
}
else if (this.Columns[e.ColumnIndex].GetType() == typeof(DataGridViewComboBoxColumn))
{
this.CurrentCell = this[e.ColumnIndex, e.RowIndex];
this.BeginEdit(false);
ComboBox comboBox = this.EditingControl as ComboBox;
if (comboBox != null)
{
comboBox.DroppedDown = true;
}
}
base.OnCellContentClick(e);
}
protected override void OnCellClick(DataGridViewCellEventArgs e)
{
if (this.Columns[e.ColumnIndex].GetType() == typeof(DataGridViewComboBoxColumn))
{
this.CurrentCell = this[e.ColumnIndex, e.RowIndex];
this.BeginEdit(false);
ComboBox comboBox = this.EditingControl as ComboBox;
if (comboBox != null)
{
comboBox.DroppedDown = true;
}
}
base.OnCellClick(e);
}
protected override void OnDataBindingComplete(DataGridViewBindingCompleteEventArgs e)
{
base.OnDataBindingComplete(e);
}
protected override void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
List<ColumnSettingsClass> LCss = new List<ColumnSettingsClass>();
foreach (DataGridViewColumn col in this.Columns)
{
if (!HiddenColumnsList.Contains(col.Name))
{
LCss.Add(new ColumnSettingsClass(col.Name, col.HeaderText, col.Width, col.Index, col.Visible));
}
}
ColumnSettings frmCs = new ColumnSettings(ref LCss);
frmCs.ShowDialog(this);
foreach (ColumnSettingsClass item in LCss)
{
if (this.Columns.Contains(item.ColumnName))
{
this.Columns[item.ColumnName].DisplayIndex = item.ColumnOrdinal;
this.Columns[item.ColumnName].Width = item.ColumnWidth;
this.Columns[item.ColumnName].Visible = item.Visibility;
}
}
}
base.OnColumnHeaderMouseClick(e);
}
protected override void OnCurrentCellDirtyStateChanged(EventArgs e)
{
base.OnCurrentCellDirtyStateChanged(e);
this.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
protected override void OnEditingControlShowing(DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox)
{
ComboBox comboBox = e.Control as ComboBox;
comboBox.SelectedIndexChanged -= new EventHandler(LastColumnComboSelectionChanged);
comboBox.SelectedIndexChanged += new EventHandler(LastColumnComboSelectionChanged);
if (comboBox != null)
comboBox.DropDown += delegate(object s, EventArgs se) { ((ComboBox)s).BackColor = this.DefaultCellStyle.BackColor; };
}
base.OnEditingControlShowing(e);
}
private void LastColumnComboSelectionChanged(object sender, EventArgs e)
{
var currentcell = this.CurrentCellAddress;
var sendingCB = sender as DataGridViewComboBoxEditingControl;
if (sendingCB.EditingControlValueChanged)
{
DataGridViewTextBoxCell cel = (DataGridViewTextBoxCell)this.Rows[currentcell.Y].Cells[0];
cel.Value = sendingCB.EditingControlFormattedValue.ToString();
}
sendingCB.SelectedIndexChanged -= new EventHandler(LastColumnComboSelectionChanged);
}
#endregion
}
你能告訴我們的代碼???? –
請添加您的控件的代碼以及如何調用/添加控件以形成。 –
該標題應該更新以實際描述問題。 – JohnSaps