How can I detect when a cell starts being edited, not when it becomes current
You can use the CurrentCellChanged event to detect when the currentcell changes position. But this event will not allow you to catch the start of a cell being edited. One way you can do this is to catch the TextChanged event in the embedded TextBox within the cell. If the text changes, then it might be the beginning of a cell edit provided the text in the TextBox differs from the stored value from the DataSource. The reason you need to check for a different value between the grid DataSource and the TextBox contents is that the TextChanged event is fired initially when the TextBox is initialized when the cell becomes current and moves the value from the grid ataSource to the TextBox. You also have to ignore subsequent hits of TextChanged as the same cell continues to be edited. Here is both a VB and C# sample that implements this strategy to flagged current cell start editing.
How can I add my custom columnstyles to the designer so I can use them in my DataGrid at design time
To use custom columnstyles in the designer, you need to do three things. 1) Derive a CustomColumnStyle to implement the functionality you want. 2) Derive a DataGridTableStyle class and add a new GridColumnStyles property that uses this derived CollectionEditor. This GridColumnStyle hides the baseclass member. 3) Derive a DataGrid and add a new TableStyles collection that uses your derived tablestyle. Both steps 2 and 3 will require you to derive a CollectionEditor and override CreateNewItemTypes to use the derived classes from each step in the designer. Here is a sample project showing how you might do these things.
How can I programatically add and remove columns in my DataGrid without modifying the DataTable datasource
You can control the columns displayed in the DataGrid through the DataGrid.TableStyle[0].GridColumnStyles collection. To do so, create a DataGridTableStyle and set its MappingName property to point to the name of your DataTable which is the DataSource for the DataGrid. Next, add this DataGridTableStyle to the DataGrid.TableStyles property. Finally, set the DataGrid.DataSource property to the DataTable. Doing things in this order, guarantees that the DataGridTableStyle.GridColumnStyles collection will be fully populated showing all the DataTable columns in the the DataGrid. Then to add and remove columns from the DataGrid, you only have to add and remove DataGridColumnStyle objects from this DataGrid.TableStyle[0].GridColumnStyles collection. Removing them is straight-forward through a Remove method call. But inserting them requires more work as there is no InsertAt method defined for this collection. To handle this problem, you can create a new array of DataGridColumnStyles, and populate this array in the necessary order to reflect the DataGrid with an inserted column. Then you can clear the old collection, and create a new collection with this new array. You really are not creating all new DataGridColumnStyle objects, but are simply reordering the existing ones in a new collection. Here is a sample project containing both C# and VB.NET code showing how you might do this.
How can I read individual frames from an animated image?
GDI+ has direct support for reading and outputting animated images. To get at the individual frames, you can use the image’s FrameDimensionList, and then call SelectActiveFrame, by passing in the dimension and the zero based frame index. First, create a new FrameDimension object: FrameDimension dimension = new System.Drawing.Imaging.FrameDimension(myImage.FrameDimensionsList[0]); Once you have the dimension, you can get the frame count: int frameCount = myImage.GetFrameCount(dimension); Now, that you know the frame count of the image, you can call SelectActiveFrame by passing in the dimension and the frame index (zero based). myImage.SelectActiveFrame(dimension,1); If the image is being viewed at runtime, then the call to SelectActiveFrame will set the current frame, and then begin to loop through again (unless it is a jpeg image). The attached sample works around this by saving the image to a MemoryStream for display – thereby capturing the one frame that is chosen. Sample Application w/Source Code C# or VB
How can I display a form that is ‘TopMost’ for only my application, but not other applications
You can do this by setting the child form’s TopMost to False and setting its Owner property to the MainForm. [C#] Form1 f = new Form1(); f.TopMost = false; f.Owner = this; f.Show(); [VB.NET] dim f as New Form1() f.TopMost = False f.Owner = Me f.Show()