请问能否实现Winform下DataGrid的某列中有些cell为ReadOnly=true,而另一些为ReadOnly=false。如有知道者,请给予详细说明。谢谢!

解决方案 »

  1.   

    用CurrentCellChanged事件,判断当前cell是否只读,设置datagrid的只读属性来控制cell的只读。
      

  2.   

    好象不能吧,只能某列只读,不能象flexcell一样可以控制单个的单元格,并可以使用合并、拆分等功能,一般从功能性和界面表现上来看,都用第3方表格控件,
      

  3.   

    mixiaobo(andy) :都有哪些第3方表格控件比较好呢?推荐几个吧,谢谢!
      

  4.   

    可以将其设置Enable设置为false,下面是完整的代码,仔细去研究吧:namespace DataGridCellxCellEnable
    {
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    using System.Data.OleDb;
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
    private System.Windows.Forms.DataGrid dataGrid1;
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.Container components = null; public Form1()
    {
    //
    // Required for Windows Form Designer support
    //
    InitializeComponent(); //
    // TODO: Add any constructor code after InitializeComponent call
    //
    } /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    protected override void Dispose( bool disposing )
    {
    if( disposing )
    {
    if (components != null) 
    {
    components.Dispose();
    }
    }
    base.Dispose( disposing );
    } #region Windows Form Designer generated code
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
    this.dataGrid1 = new System.Windows.Forms.DataGrid();
    ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
    this.SuspendLayout();
    // 
    // dataGrid1
    // 
    this.dataGrid1.DataMember = "";
    this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
    this.dataGrid1.Location = new System.Drawing.Point(48, 32);
    this.dataGrid1.Name = "dataGrid1";
    this.dataGrid1.Size = new System.Drawing.Size(456, 248);
    this.dataGrid1.TabIndex = 0;
    // 
    // Form1
    // 
    this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
    this.ClientSize = new System.Drawing.Size(544, 309);
    this.Controls.AddRange(new System.Windows.Forms.Control[] {
      this.dataGrid1});
    this.Name = "Form1";
    this.Text = "Form1";
    this.Load += new System.EventHandler(this.Form1_Load);
    ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
    this.ResumeLayout(false); }
    #endregion /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    public static void Main() 
    {
    Application.Run(new Form1());
    } private void Form1_Load(object sender, System.EventArgs e)
    {
    // Set the connection and sql strings
    // assumes your mdb file is in your root
    string connString = @"Provider=Microsoft.JET.OLEDB.4.0;data source=C:\northwind.mdb";
    string sqlString = "SELECT * FROM customers"; OleDbDataAdapter dataAdapter = null;
    DataSet _dataSet = null; try
    {
    // Connection object
    OleDbConnection connection = new OleDbConnection(connString); // Create data adapter object
    dataAdapter = new OleDbDataAdapter(sqlString, connection);

    // Create a dataset object and fill with data using data adapter's Fill method
    _dataSet = new DataSet();
    dataAdapter.Fill(_dataSet, "customers");
    connection.Close();
    }
    catch(Exception ex)
    {
    MessageBox.Show("Problem with DB access-\n\n   connection: "
    + connString + "\r\n\r\n            query: " + sqlString
    + "\r\n\r\n\r\n" + ex.ToString());
    this.Close();
    return;
    } // Create a table style that will hold the new column style 
    // that we set and also tie it to our customer's table from our DB
    DataGridTableStyle tableStyle = new DataGridTableStyle();
    tableStyle.MappingName = "customers"; // since the dataset has things like field name and number of columns,
    // we will use those to create new columnstyles for the columns in our DB table
    int numCols = _dataSet.Tables["customers"].Columns.Count;
    DataGridEnableTextBoxColumn aColumnTextColumn ;
    for(int i = 0; i < numCols; ++i)
    {
    aColumnTextColumn = new DataGridEnableTextBoxColumn(i);
    aColumnTextColumn.HeaderText = _dataSet.Tables["customers"].Columns[i].ColumnName;
    aColumnTextColumn.MappingName = _dataSet.Tables["customers"].Columns[i].ColumnName; //an EnableCell event handler
    aColumnTextColumn.CheckCellEnabled += new EnableCellEventHandler(SetEnableValues); tableStyle.GridColumnStyles.Add(aColumnTextColumn);
    }

    // make the dataGrid use our new tablestyle and bind it to our table
    dataGrid1.TableStyles.Clear();
    dataGrid1.TableStyles.Add(tableStyle); dataGrid1.DataSource = _dataSet.Tables["customers"];
    } public void SetEnableValues(object sender, DataGridEnableEventArgs e)
    {
    //do something based on the row & column to set enable flag
    if( (e.Column + e.Row) % 5 == 0)
    e.EnableValue = false;
    else
    e.EnableValue = true;

    }
    } public class DataGridEnableEventArgs : EventArgs
    {
    private int _column;
    private int _row;
    private bool _enablevalue; public DataGridEnableEventArgs(int row, int col, bool val)
    {
    _row = row;
    _column = col;
    _enablevalue = val;
    } public int Column
    {
    get{ return _column;}
    set{ _column = value;}
    }
    public int Row
    {
    get{ return _row;}
    set{ _row = value;}
    }
    public bool EnableValue
    {
    get{ return _enablevalue;}
    set{ _enablevalue = value;}
    }
    } public delegate void EnableCellEventHandler(object sender, DataGridEnableEventArgs e); public class DataGridEnableTextBoxColumn : DataGridTextBoxColumn
    {
    //in your handler, set the EnableValue to true or false, depending upon the row & col
    public event EnableCellEventHandler CheckCellEnabled;

    private int _col; public DataGridEnableTextBoxColumn(int column)
    {
    _col = column;
    } protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight)
    {
    //can remove this if you don't want to vary the color of diabled cells
    bool enabled = true;
    if(CheckCellEnabled != null)
    {
    DataGridEnableEventArgs e = new DataGridEnableEventArgs(rowNum, _col, enabled);
    CheckCellEnabled(this, e);
    if(!e.EnableValue)
    backBrush = Brushes.LightGray;
    }
    base.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight);
    } protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
    {
    bool enabled = true;
    if(CheckCellEnabled != null)
    {
    DataGridEnableEventArgs e = new DataGridEnableEventArgs(rowNum, _col, enabled);
    CheckCellEnabled(this, e);
    enabled = e.EnableValue;
    }
    if(enabled)
    base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);
    }
    }
    }