Monday, June 06, 2005

Properly Updating Data Grid Bound Values: If you ever run into a situation where you have a Data Grid bound to a Data Source and another control, such as a TextBox or ComboBox, and it's bound to the same Data Source and modifying the bound value of that control does not immediately cause the modified value to appear in the Data Grid, I have the reason why: validation.
Normally, when a situation like this occurs, simply tabbing through the controls causes the modified value to appear in the bound Data Grid. That's because the validation events are raised which in return call the control's Refresh() method. Refresh() causes the bound control(s) to invalidate their area and redraw. This includes, in this example, any data within a Data Grid.
In order for you to properly update a bound Data Grid's data whenever a bound control modifies it's values, you need to 1) first place the Focus() on the container that holds the Data Grid (a Form, GroupBox, etc.), 2) secondly, place the Focus() on the Data Grid itself and then 3) thirdly, call the Data Grid's Refresh() method.

Properly Handling KeyPress, KeyDown and KeyUp Events: always set the KeyPressEventArgs's Handled property to true whenever you want to AVOID the key pressed being sent to the application. For example, if you're checking a TextBox control to determine whether or not a user has entered a non-digit character and don't want that character to end up in the TextBox accordingly then set the Handled property to true:

Tab Order: To enable this feature, 1) first select the form on which you want to set a tab order structure, 2) click on View and then Tab Order from the VS.NET menu and then 3) click on each control in the order in which you want tabbing flow to follow.

Saturday, June 04, 2005

Providing Windows Forms Help via the HelpProvider: 1) Drag and drop the HelpProvider control onto the form in which you want to provide help, 2) in the properties tab of the HelpProvider control, click on the ... button for HelpNamespace and enter the path to a Help File (*.htm, *.chm, *.col), 3) select a control on the form for which you want to provide help and then set the ShowHelp property to true, 4) set the HelpKeyword property for the control to the name of the HTML page that pertains to this topic and then 5) set the HelpNavigator property to Topic.
Note: after doing the preceding steps, select the control for which you want to see help and then press the F1 key. Set the HelpKeyword property to a keyword in the help file's Index and then set the HelpNavigator property to KeywordIndex to have the Index lookup the keyword specified. What you enter in HelpKeyword depends ENTIRELY on what you set the HelpNavigator property to.

Providing Windows Forms Pop-up Help via the HelpProvider: 1) Drag and drop the HelpProvider control onto the form in which you want to provide pop-up help, 2) select a control on the form for which you want to provide pop-up help and then set the ShowHelp property to true, 3) set the HelpString property to whatever you want the pop-up message to display, 4) select the parent form and then set HelpButton property to true and then 5) set the form's MaximizeBox and MinimizeBox to false.
Note: after doing the preceding steps, an extra button on the control area of the title bar of the form with a question mark in it should appear: click on this button and then click on the control for which you want to display the associated pop-up help for.

Thursday, June 02, 2005

Accessing a Deleted DataRow's Data: can be accessed by retrieving it's DataRowVersion.Original values; typically, access to data is retrieved through the DataRow using it's DataRowVersion.Current values. Added, Modified and Unchanged DataRows can have their values accessed via their DataRowVersion.Current versions.

2) In the constructor of the class you want to protect, call the LicenseManager's Validate method:

System.ComponentModel.LicenseManager.Validate(typeof(MyClass));

3) Create a license file with the name of the format Namespace.Class.lic. Where Namespace.Class is the fully qualified class to be protected by the license.
4) In the license file, make sure the first line reads the following format: "Namespace.Class is a licensed component." (without the double-quotes). Care must be taken to ensure the exact sentence is written - even omitting the preiod at the end will cause the LicenseManager to throw an exception if it's not formatted perfectly.

SecurityAction.RequestOptional: isn't what it sounds like; requests the specified permission from the CLR and ALL others are implicitly refused; the specified permission is simply requested and not demanded (RequestMinimum). So, when running a Windows Forms application, [assembly: FileDialogPermission(SecurityAction.RequestOptional, Unrestricted=true)] will prevent the CLR from allowing the application to execute as ALL other permissions, including UIPermission, will be denied permission grants.

SecurityAction.RequestMinimum: demands that the CLR grant the specified permission to the application. If the run-time security policy disallows the specified permission, the application will not execute.

SecurityAction.RequestRefuse: the application lets the CLR know that the specified permission MUST NOT BE GRANTED ACCESS. If the CLR detected that the application is using the specified resource, it will now allow the application to execute.

SecurityAction.RequestOptional, SecurityAction.RequestMinimum and SecurityAction.RequestRefuse can ONLY be used at the assembly scope.

All permissions declaratively stated at the assembly scope are stored in the assembly's manifest.

Repeated Role-based Validation: Use the AppDomain.CurrentDomain's SetPrincipalPolicy method instead of the Thread's CurrentPrincipal property when consistent validation against the current principal is present. Supposedly, there's less overhead involved. The default is for the AppDomain to use the PrincipalPolicy.UnauthenticatedPrincipal policy.

Single-use Role-based Validation: When you're only going to validate a user one time, don't use the AppDomain's SetPrincipalPolicy method. Instead, set the thread's CurrentPrincipal to an instance of an IPrincipal object..

Replacing the IPrincipal Object: You will not have a problem replacing the thread's current principal with trusted code. However, semi-trusted code (Internet, Intranet zones, etc.) will cause a problem. In such a cases, make it known to the run-time that this is the permission you need for the semi-trusted code (the need to change the principal object from unmanaged code) by implementing the SecurityPermissionAttribute:..

Combining PrincipalPermission Objects: You can do this by creating two PrincipalPermission objects and joining them by using of the object's Union methods. The CLR uses an OR condition to determine whether a test succeeds. For example,.:

// Current user/principal must be part of either of
// the following two roles/groups:
PrincipalPermission pp1 = new PrincipalPermission(null, "Administrators");
PrincipalPermission pp2 = new PrincipalPermission(null, "Domain Admins");
// Set the current user:
GenericPrincipal gp1 = new GenericPrincipal(new GenericIdentity("MikeG"), new String[] { "Administrators" });
System.Threading.Thread.CurrentPrincipal = gp1;
// User must be part of the Administrators group:
pp1.Union(pp2).Demand();
// The above statement will succeed as the current
// principal is part of the Administrators group.