C# Design Patterns
C# Design patterns by James W. Cooper. ISBN: 0201844532 This is a good book to learn about patterns through a C#/Windows Forms lens. Several of the samples are UI related and use Windows Forms.
How can I use MSHTML to edit HTML in a Windows Forms control
Take a look at Tim Anderson’s HTMLEditor control which is a wrapper for MSHTML.
How can I force the vertical scrollbar in my DataGrid to always be visible
Derive a DataGrid. In your derived grid, add a handler for the VertScrollBar.VisibleChanged event. In your handler, if the scrollbar is not visible, size it and position it, and then show it. The code below assumes no horizontal scrollbar is necessary. If it is present, you would have to adjust the sizing code. C# public class MyDataGrid : DataGrid { public MyDataGrid() { //make scrollbar visible & hook up handler this.VertScrollBar.Visible = true; this.VertScrollBar.VisibleChanged += new EventHandler(ShowScrollBars); } private int CAPTIONHEIGHT = 21; private int BORDERWIDTH = 2; private void ShowScrollBars(object sender, EventArgs e) { if(!this.VertScrollBar.Visible) { int width = this.VertScrollBar.Width; this.VertScrollBar.Location = new Point(this.ClientRectangle.Width – width – BORDERWIDTH, CAPTIONHEIGHT); this.VertScrollBar.Size = new Size(width, this.ClientRectangle.Height – CAPTIONHEIGHT – BORDERWIDTH); this.VertScrollBar.Show(); } } } VB.NET Public Class MyDataGrid Inherits DataGrid Public Sub New() ’make scrollbar visible & hook up handler Me.VertScrollBar.Visible = True AddHandler Me.VertScrollBar.VisibleChanged, AddressOf ShowScrollBars End Sub ’New Private CAPTIONHEIGHT As Integer = 21 Private BORDERWIDTH As Integer = 2 Private Sub ShowScrollBars(sender As Object, e As EventArgs) If Not Me.VertScrollBar.Visible Then Dim width As Integer = Me.VertScrollBar.Width Me.VertScrollBar.Location = New Point(Me.ClientRectangle.Width – width – BORDERWIDTH, CAPTIONHEIGHT) Me.VertScrollBar.Size = New Size(width, Me.ClientRectangle.Height – CAPTIONHEIGHT – BORDERWIDTH) Me.VertScrollBar.Show() End If End Sub ’ShowScrollBars End Class ’MyDataGrid
How do I prevent the datagrid from displaying its append row (the row at the end with an asterisk)
The DataGrid class does not have a property that controls whether a new row can be added. But the DataView class does have such a property (along with some others such as AllowEdit and AllowDelete). Here is code that will turn off the append row by getting at the dataview associated with the datagrid. string connString = @’Provider=Microsoft.JET.OLEDB.4.0;data source=C:\northwind.mdb’; string sqlString = ‘SELECT * FROM customers’; // Connection object OleDbConnection connection = new OleDbConnection(connString); // Create data adapter object OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sqlString, connection); // Create a dataset object and fill with data using data adapter’s Fill method DataSet dataSet = new DataSet(); dataAdapter.Fill(dataSet, ‘customers’); // Attach dataset’s DefaultView to the datagrid control dataGrid1.DataSource = dataSet.Tables[‘customers’]; //no adding of new rows thru dataview… CurrencyManager cm = (CurrencyManager)this.BindingContext[dataGrid1.DataSource, dataGrid1.DataMember]; ((DataView)cm.List).AllowNew = false; If your datagrid contains links, then Matthew Miller suggest adding Navigate handler such as the one below to disallow the AddNew. private void DataGrid1_Navigate(object sender, System.Windows.Forms.NavigateEventArgs ne) { if(ne.Forward) { CurrencyManager cm = (CurrencyManager)BindingContext[DataGrid1.DataSource,DataGrid1.DataMember]; DataView dv = (DataView) cm.List; dv.AllowNew = false; } }
How can I use ’Hooks’ in .NET
Please check out this article from the October 2000 issue of MSDN Magazine. Allen Weng gives the following explanation in a post on the microsoft.public.dotnet.framework.windowsforms newgroup. If what you are looking for is just to intercept and handle generic Windows messages such as WM_NCPAINT or alike, you can override WndProc (). You don’t need to use the hook procedure. Here is some code that does this: public enum WinMsg { WM_KEYDOWN = 256, WM_KEYUP = 257, WM_PAINT = 15, WM_CREATE = 1 ……. ……. }; protected override void WndProc(ref System.Windows.Forms.Message m) { ………….. if (m.Msg == (int) WinMsg.WM_PAINT) { m.Result = new IntPtr(0); // no further processing is needed. ……. ……. } ………….. base.WndProc(ref m); } But if you need to use a hook procedure, be cautious since they might interfere with normal execution of other applications. In some extreme cases, they might bring the whole system down if not processed correctly. Here is the code snippet that shows you how to do implement and use the hook procedure in .NET: public class Win32Hook { [DllImport(‘kernel32’)] public static extern int GetCurrentThreadId(); [DllImport( ‘user32’, CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)] public static extern int SetWindowsHookEx( HookType idHook, HOOKPROC lpfn, int hmod, int dwThreadId ); public enum HookType { WH_KEYBOARD = 2 } public delegate int HOOKPROC(int nCode, int wParam, int lParam); private HOOKPROC hookProc; //private field with class scope public void SetHook() { // set the keyboard hook hookProc = new HOOKPROC(this.MyKeyboardProc); SetWindowsHookEx(HookType.WH_KEYBOARD, hookProc, 0, GetCurrentThreadId()); } public int MyKeyboardProc(int nCode, int wParam, int lParam) { return 0; } } To install the hook procedure Win32Hook hook = new Win32Hook(); hook.SetHook();