How can I prevent a particular cell from being editable
You can do this by deriving a custom column style and overriding its virtual Edit member. Below is an override that will prevent the cell in row 1 of the column from getting the edit focus. You can paste this code in the DataGridDigitsTextBoxColumn sample to see it work. If you want a more flexible solution, you could expose an event as part of your derived columnstyle that fires right before the call to the baseclass in the Edit override. This would allow the handler of the event to set the enable value depending upon the row and column parameters that are passed as part of the event args. You can download a sample (C#, VB) that implements this technique. The sample also fires the event right before painting the cell to decide whether to paint a gray background for the disabled cell. You could modify the eventargs to include a backcolor, and use this event to color cells based on row and column values. //this override will prevent the cell in row 1 from getting the edit focus protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible) { if(rowNum == 1) return; base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible); }
How do I prevent sorting a single column in my DataGrid
You can do this by deriving the DataGrid and overriding OnMouseDown. In your override, do a HitText and if the hit is on a column header that you do not want to sort, do not call the baseclass. Here is a code that sorts all columns except the second column. [C#] //derived class public class MyDataGrid : DataGrid { protected override void OnMouseDown(MouseEventArgs e) { Point pt = new Point(e.X, e.Y); DataGrid.HitTestInfo hti = this.HitTest(pt); if (hti.Type == HitTestType.ColumnHeader && hti.Column == 1) { //don’t sort col 1 return; //don’t call baseclass } base.OnMouseDown(e); } } [VB.NET] ‘derived class Public Class MyDataGrid Inherits DataGrid Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs) Dim pt As New Point(e.X, e.Y) Dim hti As DataGrid.HitTestInfo = Me.HitTest(pt) If hti.Type = HitTestType.ColumnHeader AndAlso hti.Column = 1 Then ‘don’t sort col 1 Return ‘don’t call baseclass End If MyBase.OnMouseDown(e) End Sub ‘OnMouseDown End Class ‘MyDataGrid
How do I use the DataColumn.Expression property to add a computed/combined column to my datagrid
The idea is to load your datatable in a normal fashion. Once the datatable is loaded, you can add an additional column that is computed from the other columns in your datatable. In the sample(CS, VB), we load the CustomerID, CompanyName, ContactName and ContactTitle from the Customers table in the NorthWind database. We then add an additional column that concatenates the ContactName and ContactTitle into one column. To add the additional column, we create a DataColumn, set a mapping name, and then use the Expression property to define how the column is to be computed. [C#] DataColumn dc = new DataColumn(”Contact”, typeof(string)); dc.Expression = ”ContactName + ’:’ +ContactTitle”; _dataSet.Tables[”customers”].Columns.Add(dc); [VB.NET] Dim dc As DataColumn dc = New DataColumn(”Contact”, GetType(System.String)) dc.Expression = ”ContactName + ’:’ +ContactTitle” _dataSet.Tables(”customers”).Columns.Add(dc) The sample actually shows two datagrids. The first one uses the default binding to display the entire table including our added column. In the second datagrid, we add a custom DataGridTableStyle to only display the CustomerID, CompanyName and our added column.
How can I programmatically move through a dataset that has bound controls?
You have to access a property called the Binding Context and then retrieve the BindingContext associated with the dataset and data member that you used for binding. After you have access to this object you just set the position property. You can move backward and forward through the dataset. Download a working sample that shows this: simpledata5.zip form.BindingContext[this.dataSet, ”Customers”].Position -= 1; Remember that when you scroll through the dataset all associated controls will scroll since they all depend on the same context. This is useful if you want to have several controls that display sections of a row operate in tandem.
How do I add updating support to a dataset?
To be able to write changes back to the datasource, the data adapter object that populates your dataset should have commands set for updating, deleting etc. Fortunately, there is a class called SqlCommandBuilder that generates these commands from our Select command. All we have to do is instantiate this class passing it in the data adapter that we use. Enclosed is a complete sample: simpledata4.zip // Command builder will generate the command required to update the // datasource from your select statement SqlCommandBuilder commandBuilder = new SqlCommandBuilder(this.dataAdapter); After this is done whenever you wish to write changes back to the data source simply call Update on the data adapter as shown below. if(this.dataSet != null && this.dataSet.HasChanges()) this.dataAdapter.Update(this.dataSet, ”Customers”);