2012-01-18 13 views
5

realtà io hanno risolto il problema di avere casella nell'intestazione di un DGV, ecco il codiceCasella nell'intestazione di un DataGridView in qualsiasi colonna

Rectangle rect = dataGridView1.GetCellDisplayRectangle(0, -1, true); 
     rect.Y = 3; 
     rect.X = rect.Location.X + (rect.Width/4); 
     CheckBox checkboxHeader = new CheckBox(); 
     checkboxHeader.Name = "checkboxHeader"; 
     //datagridview[0, 0].ToolTipText = "sdfsdf"; 
     checkboxHeader.Size = new Size(18, 18); 
     checkboxHeader.Location = rect.Location; 
     checkboxHeader.CheckedChanged += new EventHandler(checkboxHeader_CheckedChanged); 
     dataGridView1.Controls.Add(checkboxHeader);  

realtà prima aggiungo una colonna nella mia DGV cui è un DataGridViewCheckBoxColumn e quindi nel caricamento del modulo aggiungendo il codice sopra, il mio problema è come potete vedere qui sotto per la prima colonna funziona benissimo dato che posso impostare il rect.X nel codice per quella colonna ma per quanto riguarda il notificatore colonna come posso sapere dove si trova la posizione dell'intestazione di questa colonna a livello di codice poiché la colonna del registro può cambiare attraverso la massimizzazione e questo materiale.

enter image description here Infine, Come posso sapere ad esempio qual è la posizione del titolo della colonna [3] programatically .... Grazie in anticipo

+1

Sono molto confuso su quale sia la tua domanda qui. Sembra che tu abbia già risolto la domanda posta nel tuo titolo ... –

+0

La domanda principale è come posso recuperare la posizione o la posizione di una cella in datagridview e considerare che alcune colonne come "log" qui possono essere nel Autosize = Fill mode! – Ehsan

risposta

15

provare questo

#region GridViewCheckBoxColumn 


    [System.Drawing.ToolboxBitmap(typeof(System.Windows.Forms.DataGridViewCheckBoxColumn))] 
    public class GridViewCheckBoxColumn : DataGridViewCheckBoxColumn 
    { 
     #region Constructor 

     public GridViewCheckBoxColumn() 
     { 
      DatagridViewCheckBoxHeaderCell datagridViewCheckBoxHeaderCell = new DatagridViewCheckBoxHeaderCell(); 

      this.HeaderCell = datagridViewCheckBoxHeaderCell; 
      this.Width = 50; 

      //this.DataGridView.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.grvList_CellFormatting); 
      datagridViewCheckBoxHeaderCell.OnCheckBoxClicked += new CheckBoxClickedHandler(datagridViewCheckBoxHeaderCell_OnCheckBoxClicked); 

     } 

     #endregion 

     #region Methods 

     void datagridViewCheckBoxHeaderCell_OnCheckBoxClicked(int columnIndex, bool state) 
     { 
      DataGridView.RefreshEdit(); 

      foreach (DataGridViewRow row in this.DataGridView.Rows) 
      { 
       if (!row.Cells[columnIndex].ReadOnly) 
       { 
        row.Cells[columnIndex].Value = state; 
       } 
      } 
      DataGridView.RefreshEdit(); 
     } 



     #endregion 
    } 

    #endregion 

    #region DatagridViewCheckBoxHeaderCell 

    public delegate void CheckBoxClickedHandler(int columnIndex, bool state); 
    public class DataGridViewCheckBoxHeaderCellEventArgs : EventArgs 
    { 
     bool _bChecked; 
     public DataGridViewCheckBoxHeaderCellEventArgs(int columnIndex, bool bChecked) 
     { 
      _bChecked = bChecked; 
     } 
     public bool Checked 
     { 
      get { return _bChecked; } 
     } 
    } 
    class DatagridViewCheckBoxHeaderCell : DataGridViewColumnHeaderCell 
    { 
     Point checkBoxLocation; 
     Size checkBoxSize; 
     bool _checked = false; 
     Point _cellLocation = new Point(); 
     System.Windows.Forms.VisualStyles.CheckBoxState _cbState = 
     System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal; 
     public event CheckBoxClickedHandler OnCheckBoxClicked; 

     public DatagridViewCheckBoxHeaderCell() 
     { 
     } 

     protected override void Paint(System.Drawing.Graphics graphics, 
     System.Drawing.Rectangle clipBounds, 
     System.Drawing.Rectangle cellBounds, 
     int rowIndex, 
     DataGridViewElementStates dataGridViewElementState, 
     object value, 
     object formattedValue, 
     string errorText, 
     DataGridViewCellStyle cellStyle, 
     DataGridViewAdvancedBorderStyle advancedBorderStyle, 
     DataGridViewPaintParts paintParts) 
     { 
      base.Paint(graphics, clipBounds, cellBounds, rowIndex, 
      dataGridViewElementState, value, 
      formattedValue, errorText, cellStyle, 
      advancedBorderStyle, paintParts); 
      Point p = new Point(); 
      Size s = CheckBoxRenderer.GetGlyphSize(graphics, 
      System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal); 
      p.X = cellBounds.Location.X + 
      (cellBounds.Width/2) - (s.Width/2); 
      p.Y = cellBounds.Location.Y + 
      (cellBounds.Height/2) - (s.Height/2); 
      _cellLocation = cellBounds.Location; 
      checkBoxLocation = p; 
      checkBoxSize = s; 
      if (_checked) 
       _cbState = System.Windows.Forms.VisualStyles. 
       CheckBoxState.CheckedNormal; 
      else 
       _cbState = System.Windows.Forms.VisualStyles. 
       CheckBoxState.UncheckedNormal; 
      CheckBoxRenderer.DrawCheckBox 
      (graphics, checkBoxLocation, _cbState); 
     } 

     protected override void OnMouseClick(DataGridViewCellMouseEventArgs e) 
     { 
      Point p = new Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y); 
      if (p.X >= checkBoxLocation.X && p.X <= 
      checkBoxLocation.X + checkBoxSize.Width 
      && p.Y >= checkBoxLocation.Y && p.Y <= 
      checkBoxLocation.Y + checkBoxSize.Height) 
      { 
       _checked = !_checked; 
       if (OnCheckBoxClicked != null) 
       { 
        OnCheckBoxClicked(e.ColumnIndex, _checked); 
        this.DataGridView.InvalidateCell(this); 
       } 
      } 
      base.OnMouseClick(e); 
     } 

    } 

    #endregion 

    #region ColumnSelection 

    class DataGridViewColumnSelector 
    { 
     // the DataGridView to which the DataGridViewColumnSelector is attached 
     private DataGridView mDataGridView = null; 
     // a CheckedListBox containing the column header text and checkboxes 
     private CheckedListBox mCheckedListBox; 
     // a ToolStripDropDown object used to show the popup 
     private ToolStripDropDown mPopup; 

     /// <summary> 
     /// The max height of the popup 
     /// </summary> 
     public int MaxHeight = 300; 
     /// <summary> 
     /// The width of the popup 
     /// </summary> 
     public int Width = 200; 

     /// <summary> 
     /// Gets or sets the DataGridView to which the DataGridViewColumnSelector is attached 
     /// </summary> 
     public DataGridView DataGridView 
     { 
      get { return mDataGridView; } 
      set 
      { 
       // If any, remove handler from current DataGridView 
       if (mDataGridView != null) mDataGridView.CellMouseClick -= new DataGridViewCellMouseEventHandler(mDataGridView_CellMouseClick); 
       // Set the new DataGridView 
       mDataGridView = value; 
       // Attach CellMouseClick handler to DataGridView 
       if (mDataGridView != null) mDataGridView.CellMouseClick += new DataGridViewCellMouseEventHandler(mDataGridView_CellMouseClick); 
      } 
     } 

     // When user right-clicks the cell origin, it clears and fill the CheckedListBox with 
     // columns header text. Then it shows the popup. 
     // In this way the CheckedListBox items are always refreshed to reflect changes occurred in 
     // DataGridView columns (column additions or name changes and so on). 
     void mDataGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) 
     { 
      if (e.Button == MouseButtons.Right && e.RowIndex == -1 && e.ColumnIndex == 0) 
      { 
       mCheckedListBox.Items.Clear(); 
       foreach (DataGridViewColumn c in mDataGridView.Columns) 
       { 
        mCheckedListBox.Items.Add(c.HeaderText, c.Visible); 
       }     
       int PreferredHeight = (mCheckedListBox.Items.Count * 16) + 7; 
       mCheckedListBox.Height = (PreferredHeight < MaxHeight) ? PreferredHeight : MaxHeight; 
       mCheckedListBox.Width = this.Width; 
       mPopup.Show(mDataGridView.PointToScreen(new Point(e.X, e.Y))); 
      } 
     } 

     // The constructor creates an instance of CheckedListBox and ToolStripDropDown. 
     // the CheckedListBox is hosted by ToolStripControlHost, which in turn is 
     // added to ToolStripDropDown. 
     public DataGridViewColumnSelector() 
     { 
      mCheckedListBox = new CheckedListBox(); 
      mCheckedListBox.CheckOnClick = true; 
      mCheckedListBox.ItemCheck += new ItemCheckEventHandler(mCheckedListBox_ItemCheck); 

      ToolStripControlHost mControlHost = new ToolStripControlHost(mCheckedListBox); 
      mControlHost.Padding = Padding.Empty; 
      mControlHost.Margin = Padding.Empty; 
      mControlHost.AutoSize = false; 

      mPopup = new ToolStripDropDown(); 
      mPopup.Padding = Padding.Empty; 
      mPopup.Items.Add(mControlHost); 
     } 

     public DataGridViewColumnSelector(DataGridView dgv) 
      : this() 
     { 
      this.DataGridView = dgv; 
     } 

     // When user checks/unchecks a checkbox, the related column visibility is 
     // switched. 
     void mCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e) 
     { 
      mDataGridView.Columns[e.Index].Visible = (e.NewValue == CheckState.Checked); 
     } 
    } 

    #endregion 
+0

ok questo va bene, ma quando voglio mettere un chechboxheader per la colonna di notifica come posso sapere la posizione di quello e definire andare a quella colonna! :( – Ehsan

+0

E potresti per favore cosa sta facendo esattamente questo codice e come posso usare questo per il mio scopo? thx – Ehsan

+0

aggiungi questo come una classe componente quindi aggiungi colulmn di tipo GridViewCheckBoxColumn puoi vederlo funzionante – Nighil

5

Questo soluzione funziona per me, aggiunge la casella di controllo alla cella di intestazione. Non vi resta che implementare il metodo "controllare tutti" e, infine, un metodo "sulla colonna di ridimensionamento" (per sostituire casella di controllo nel centro)

// Creating checkbox without panel 
CheckBox checkbox = new CheckBox(); 
checkbox.Size = new System.Drawing.Size(15, 15); 
checkbox.BackColor = Color.Transparent; 

// Reset properties 
checkbox.Padding = new Padding(0); 
checkbox.Margin = new Padding(0); 
checkbox.Text = ""; 

// Add checkbox to datagrid cell 
myDataGrid.Controls.Add(checkbox); 
DataGridViewHeaderCell header = myDataGrid.Columns[myColumnWithCheckboxes.Index].HeaderCell; 
checkbox.Location = new Point(
    header.ContentBounds.Left + (header.ContentBounds.Right - header.ContentBounds.Left + checkbox.Size.Width)/2, 
    header.ContentBounds.Top + (header.ContentBounds.Bottom - header.ContentBounds.Top + checkbox.Size.Height)/2 
); 
1

La risposta di 56ka è PERFEKT per me. Ho appena fissa l'ubicazione (2px)

private CheckBox ColumnCheckbox(DataGridView dataGridView) 
    { 
     CheckBox checkBox = new CheckBox(); 
     checkBox.Size = new Size(15, 15); 
     checkBox.BackColor = Color.Transparent; 

     // Reset properties 
     checkBox.Padding = new Padding(0); 
     checkBox.Margin = new Padding(0); 
     checkBox.Text = ""; 

     // Add checkbox to datagrid cell 
     dataGridView.Controls.Add(checkBox); 
     DataGridViewHeaderCell header = dataGridView.Columns[0].HeaderCell; 
     checkBox.Location = new Point(
      (header.ContentBounds.Left + 
      (header.ContentBounds.Right - header.ContentBounds.Left + checkBox.Size.Width) 
      /2) - 2, 
      (header.ContentBounds.Top + 
      (header.ContentBounds.Bottom - header.ContentBounds.Top + checkBox.Size.Height) 
      /2) - 2); 
     return checkBox; 
    } 
1
public class DataGridViewEx : DataGridView 
{ 
    Dictionary<DataGridViewColumn, bool> dictionaryCheckBox = new Dictionary<DataGridViewColumn, bool>(); 

    System.Drawing.Bitmap[] bmCheckBox = new System.Drawing.Bitmap[2]; 

    bool executarValueChanged = true; 

    public DataGridViewEx() 
     : base() 
    { 
     #region CheckBox no header da coluna 

     CheckBox chkTemp = new CheckBox(); 

     chkTemp.AutoSize = true; 
     chkTemp.BackColor = System.Drawing.Color.Transparent; 
     chkTemp.Size = new System.Drawing.Size(16, 16); 
     chkTemp.UseVisualStyleBackColor = false; 

     bmCheckBox[0] = new System.Drawing.Bitmap(chkTemp.Width, chkTemp.Height); 
     bmCheckBox[1] = new System.Drawing.Bitmap(chkTemp.Width, chkTemp.Height); 

     chkTemp.Checked = false; 
     chkTemp.DrawToBitmap(bmCheckBox[0], new System.Drawing.Rectangle(0, 0, chkTemp.Width, chkTemp.Height)); 

     chkTemp.Checked = true; 
     chkTemp.DrawToBitmap(bmCheckBox[1], new System.Drawing.Rectangle(0, 0, chkTemp.Width, chkTemp.Height)); 

     #endregion 
    } 

    public void CheckBoxHeader(DataGridViewCheckBoxColumn column, bool enabled) 
    { 
     if (enabled == true) 
     { 
      if (dictionaryCheckBox.Any(f => f.Key == column) == false) 
      { 
       dictionaryCheckBox.Add(column, false); 
       this.InvalidateCell(column.HeaderCell); 
      } 
     } 
     else 
     { 
      dictionaryCheckBox.Remove(column); 

      this.InvalidateCell(column.HeaderCell); 
     } 
    } 

    protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e) 
    { 
     base.OnCellPainting(e); 

     if (e.ColumnIndex >= 0 && e.RowIndex == -1 && dictionaryCheckBox.Any(f => f.Key == this.Columns[e.ColumnIndex]) == true) 
     { 
      Bitmap bmp = dictionaryCheckBox[this.Columns[e.ColumnIndex]] == true ? bmCheckBox[1] : bmCheckBox[0]; 

      Rectangle imageBounds = new Rectangle(new Point(e.CellBounds.Location.X + (e.CellBounds.Width/2) - (bmp.Size.Width/2), e.CellBounds.Location.Y + (e.CellBounds.Height/2) - (bmp.Size.Height/2)), bmp.Size); 

      e.PaintBackground(e.CellBounds, true); 
      e.PaintContent(e.CellBounds); 
      e.Graphics.DrawImage(bmp, imageBounds); 
      e.Handled = true; 
     } 
    } 

    protected override void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e) 
    { 
     base.OnColumnHeaderMouseClick(e); 

     if (dictionaryCheckBox.ContainsKey(this.Columns[e.ColumnIndex]) == true) 
     { 
      var header = this.Columns[e.ColumnIndex].HeaderCell; 
      Bitmap img = dictionaryCheckBox[this.Columns[e.ColumnIndex]] == true ? bmCheckBox[1] : bmCheckBox[0]; 

      if (e.Button == System.Windows.Forms.MouseButtons.Left && 
       e.Y >= header.ContentBounds.Y + (header.Size.Height/2) - (img.Height/2) && 
       e.Y <= header.ContentBounds.Y + (header.Size.Height/2) + (img.Height/2) && 
       e.X >= header.ContentBounds.X + (this.Columns[e.ColumnIndex].Width/2) - (img.Width/2) && 
       e.X <= header.ContentBounds.X + (this.Columns[e.ColumnIndex].Width/2) + (img.Width/2)) 
      { 
       dictionaryCheckBox[this.Columns[e.ColumnIndex]] = !dictionaryCheckBox[this.Columns[e.ColumnIndex]]; 

       this.InvalidateCell(this.Columns[e.ColumnIndex].HeaderCell); 

       executarValueChanged = false; 
       for (Int32 i = 0; i < this.Rows.Count; i++) 
       { 
        this.Rows[i].Cells[e.ColumnIndex].Value = dictionaryCheckBox[this.Columns[e.ColumnIndex]]; 
        this.RefreshEdit(); 
       } 
       executarValueChanged = true; 
      } 

     } 
    } 

    protected override void OnRowsAdded(DataGridViewRowsAddedEventArgs e) 
    { 
     base.OnRowsAdded(e); 

     List<DataGridViewColumn> listColunas = this.Columns.Cast<DataGridViewColumn>().Where(f => f.GetType() == typeof(DataGridViewCheckBoxColumn)).ToList(); 
     foreach (DataGridViewColumn coluna in listColunas) 
     { 
      if (dictionaryCheckBox.ContainsKey(coluna) == true) 
      { 
       if (dictionaryCheckBox[coluna] == true) 
       { 
        executarValueChanged = false; 

        this.Rows[e.RowIndex].Cells[coluna.Index].Value = true; 
        this.RefreshEdit(); 

        executarValueChanged = true; 
       } 
      } 
     } 
    } 

    protected override void OnRowsRemoved(DataGridViewRowsRemovedEventArgs e) 
    { 
     base.OnRowsRemoved(e); 

     List<DataGridViewColumn> listColunas = this.Columns.Cast<DataGridViewColumn>().Where(f => f.GetType() == typeof(DataGridViewCheckBoxColumn)).ToList(); 
     foreach (DataGridViewColumn coluna in listColunas) 
     { 
      if (dictionaryCheckBox.ContainsKey(coluna) == true) 
      { 
       if (this.Rows.Count == 0) 
       { 
        dictionaryCheckBox[coluna] = false; 
        this.InvalidateCell(coluna.HeaderCell); 
       } 
       else 
       { 
        Int32 numeroLinhas = this.Rows.Cast<DataGridViewRow>().Where(f => Convert.ToBoolean(f.Cells[coluna.Index].Value) == true).Count(); 
        if (numeroLinhas == this.Rows.Count) 
        { 
         dictionaryCheckBox[coluna] = true; 
         this.InvalidateCell(coluna.HeaderCell); 
        } 
       } 
      } 
     } 
    } 

    protected override void OnCellValueChanged(DataGridViewCellEventArgs e) 
    { 
     base.OnCellValueChanged(e); 

     if (e.ColumnIndex >= 0 && e.RowIndex >= 0) 
     { 
      if (dictionaryCheckBox.ContainsKey(this.Columns[e.ColumnIndex]) == true) 
      { 
       if (executarValueChanged == false) 
       { 
        return; 
       } 

       Boolean existeFalse = this.Rows.Cast<DataGridViewRow>().Any(f => Convert.ToBoolean(f.Cells[e.ColumnIndex].Value) == false); 

       if (existeFalse == true) 
       { 
        if (dictionaryCheckBox[this.Columns[e.ColumnIndex]] == true) 
        { 
         dictionaryCheckBox[this.Columns[e.ColumnIndex]] = false; 
         this.InvalidateCell(this.Columns[e.ColumnIndex].HeaderCell); 
        } 
       } 
       else 
       { 
        dictionaryCheckBox[this.Columns[e.ColumnIndex]] = true; 
        this.InvalidateCell(this.Columns[e.ColumnIndex].HeaderCell); 
       } 
      } 
     } 
    } 

    protected override void OnCurrentCellDirtyStateChanged(EventArgs e) 
    { 
     base.OnCurrentCellDirtyStateChanged(e); 

     if (this.CurrentCell is DataGridViewCheckBoxCell) 
     { 
      this.CommitEdit(DataGridViewDataErrorContexts.Commit); 
     } 
    } 
} 

uso:

dataGridViewEx1.CheckBoxHeader (dataGridViewEx1.Columns [0] come DataGridViewCheckBoxColumn, true);

0

Ho utilizzato l'evento dataGridView_CellPainting.

Su quell'evento ho inserito un'istruzione condizionale per impostare la posizione della mia casella di controllo all'interno della cella dell'intestazione, ad es. colonna 1 riga 0.

CellBounds ha un numero di proprietà che possono essere utilizzate nell'impostazione della posizione. Ho preso la parte destra della cella "e.CellBounds.Right" e quindi ho sottratto la larghezza della casella di controllo per inserire la casella di controllo nell'angolo destro della cella dell'intestazione.

void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) 
    { 
    if (e.ColumnIndex == 1 && e.RowIndex == 0) 
     { 
     TopCheckBox.Left = e.CellBounds.Right - 15; 
     } 
    } 
0

Per me, la soluzione più pulita da "56ka" e questo è il mio aggiornamento su di esso (ancora manca è la capacità di staccarsi dalla rete e DataSource). Con questo si mantiene la capacità di ordinare e vedere la direzione di ordinamento e di avere un'etichetta accanto alla casella di controllo, la normale casella di controllo e tutto ciò che ha da offrire. Realizzato in .NET Framework 4.0 per DataTable.

public static CheckBox AddHeaderCheckBox(this DataGridViewColumn column, HorizontalAlignment align = HorizontalAlignment.Center, int leftBorderOffset = 0, int rightBorderOffset = 0) 
    { 
     if (column.DataGridView == null) throw new ArgumentNullException("First you need to add the column to grid."); 

     // Creating checkbox without panel 
     CheckBox checkbox = new CheckBox(); 
     checkbox.Name = "chk" + column.Name; 
     checkbox.Size = new Size(15, 15); 
     checkbox.BackColor = Color.Transparent; 
     checkbox.Enabled = !column.ReadOnly; 

     // Reset properties 
     checkbox.Padding = new Padding(0); 
     checkbox.Margin = new Padding(0); 
     checkbox.Text = ""; 

     var changedByUser = true; 
     var dgv = column.DataGridView; 

     checkbox.CheckedChanged += (s, e) => 
     { 
      if (changedByUser) 
      { 
       try 
       { 
        changedByUser = false; 

        if (dgv.IsCurrentCellInEditMode && dgv.CurrentCell.OwningColumn.Name.Equals(column.Name)) 
         dgv.EndEdit(); 

        var dgvRows = dgv.SelectedRows.Count < 2 ? (ICollection)dgv.Rows : dgv.SelectedRows; 

        if (column.IsDataBound) 
        { 
         //adding to list because of BindingSource sort by that column 
         var rows = new List<DataRow>(); 
         foreach (DataGridViewRow row in dgvRows) 
          rows.Add(((DataRowView)row.DataBoundItem).Row); 

         foreach (var dr in rows) 
         { 
          var val = dr[column.DataPropertyName]; 
          if ((val is bool && (bool)val) != checkbox.Checked) 
           dr[column.DataPropertyName] = checkbox.Checked; 
         } 
        } 
        else 
        { 
         foreach (DataGridViewRow dgr in dgvRows) 
         { 
          var cell = dgr.Cells[column.Name]; 
          if ((cell.Value is bool && (bool)cell.Value) != checkbox.Checked) 
           cell.Value = checkbox.Checked; 
         } 
        } 
       } 
       finally 
       { 
        changedByUser = true; 
       } 
      } 
     }; 

     // Add checkbox to datagrid cell 
     dgv.Controls.Add(checkbox); 

     Action onColResize =() => 
     { 
      var colCheck = dgv.Columns[column.Name]; 
      if (colCheck == null) return; 
      int colLeft = (dgv.RowHeadersVisible ? dgv.RowHeadersWidth : 0) - dgv.HorizontalScrollingOffset; 
      foreach (DataGridViewColumn col in dgv.Columns) 
      { 
       if (col.DisplayIndex >= colCheck.DisplayIndex) break; 
       if (!col.Visible) continue; 
       colLeft += col.Width; 
      } 

      var newPoint = new Point(colLeft, dgv.ColumnHeadersHeight/2 - checkbox.Height/2); 

      if (align == HorizontalAlignment.Left) 
       newPoint.X += 3; 
      else if (align == HorizontalAlignment.Center) 
       newPoint.X += colCheck.Width/2 - checkbox.Width/2; 
      else if (align == HorizontalAlignment.Right) 
       newPoint.X += colCheck.Width - checkbox.Width - 3; 

      var minLeft = colLeft + leftBorderOffset; 
      var maxLeft = colLeft + colCheck.Width - checkbox.Width + rightBorderOffset; 

      if (newPoint.X < minLeft) newPoint.X = minLeft; 
      if (newPoint.X > maxLeft) newPoint.X = maxLeft; 

      checkbox.Location = newPoint; 
     }; 
     dgv.ColumnWidthChanged += (s, e) => onColResize(); 
     dgv.ColumnHeadersHeightChanged += (s, e) => onColResize(); 
     dgv.Scroll += (s, e) => onColResize(); 
     dgv.Resize += (s, e) => onColResize(); 
     dgv.Sorted += (s, e) => onColResize(); 

     Action<object> onDataChanged = (e) => 
     { 
      if (!changedByUser) return; 
      if (e is DataColumnChangeEventArgs) 
      { 
       if (!((DataColumnChangeEventArgs)e).Column.ColumnName.Equals(column.Name)) 
        return; 
      } 
      else if (e is ListChangedEventArgs) 
      { 
       var prop = ((ListChangedEventArgs)e).PropertyDescriptor; 
       if (prop != null && !prop.Name.Equals(column.DataPropertyName)) 
        return; 
      } 

      bool allAreTrue = true; 
      foreach (DataGridViewRow row in dgv.SelectedRows.Count < 2 ? (ICollection)dgv.Rows : dgv.SelectedRows) 
      { 
       var val = row.Cells[column.Name].Value; 
       if (!(val is bool) || !(bool)val) 
       { 
        allAreTrue = false; 
        break; 
       } 
      } 

      try 
      { 
       changedByUser = false; 
       checkbox.Checked = allAreTrue; 
      } 
      finally 
      { 
       changedByUser = true; 
      } 
     }; 
     dgv.SelectionChanged += (s, e) => onDataChanged(e); 
     if (dgv.DataSource is BindingSource) 
      ((BindingSource)dgv.DataSource).ListChanged += (s, e) => onDataChanged(e); 
     else if (dgv.DataSource is DataSet) 
      ((DataSet)dgv.DataSource).Tables[dgv.DataMember].ColumnChanged += (s, e) => onDataChanged(e); 
     else if (dgv.DataSource is DataTable) 
      ((DataTable)dgv.DataSource).ColumnChanged += (s, e) => onDataChanged(e); 

     return checkbox; 
    } 
0

Hove perso qualcosa quando si rimuove una colonna e aggiungere un altro allo stesso indice

aggiungere questo nella funzione AddHeaderCheckBox

Action onColRemoved =() => 
{ 
    checkbox.Dispose(); 
}; 
dgv.ColumnRemoved += (s, e) => onColRemoved(); 

e modificare questo:

foreach (DataGridViewRow row in dgv.SelectedRows.Count < 2 ? (ICollection) dgv.Rows : dgv.SelectedRows) 
{ 
    var val = row.Cells[column.Name].Value; 
    if (!(val is bool) || !(bool) val) 
    { 
     allAreTrue = false; 
     break; 
    } 
} 

in questo

foreach (DataGridViewRow row in dgv.SelectedRows.Count < 2 ? (ICollection) dgv.Rows : dgv.SelectedRows) 
{ 
    if (dgv.Columns.Contains(column.Name)) 
    { 
     var val = row.Cells[column.Name].Value; 
     if (!(val is bool) || !(bool) val) 
     { 
      allAreTrue = false; 
      break; 
     } 
    } 
} 
0

È necessario chiamare l'evento click sulla colonna Identificando la colonna si è fatto clic, è possibile accedere alla riga desiderata e modificare il valore del campo corrispondente ad esempio:

private void dataGridViewOrderState_CellClick(object sender, DataGridViewCellEventArgs e) 
    { 
     if (e.ColumnIndex == dataGridViewOrderState.Columns["selectedDataGridViewCheckBoxColumn"].Index) 
     { 
      var bid = dataGridViewOrderState.Rows[e.RowIndex]; 
      var selectedRow = (OrderStateLocal)bid.DataBoundItem; 
      if (selectedRow == null) 
       return; 
      selectedRow.Selected = !selectedRow.Selected; 
     } 

    } 
Problemi correlati