Tuesday, August 3, 2010

Resize WinForm Controls Automatically

Let' say you have a form with a ListBox and OK and Cancel buttons.
 




You want controls to be resized automatically when a form is resized. This is how you can achieve this by using the Anchor property:

Place all controls inside a GroupBox. Set the Anchor and Dock properties

GroupBox properties:
Anchor : Top, Bottom, Left, Right
Dock : None

Buttons properties:
Anchor : Bottom, Right
Dock : None

ListBox properties:
Anchor : Top, Bottom, Left, Right
Dock : None

Save Window Position in Registry

This is how you could save a Window position in the Registry so that the Window position could be restored next time the Form loads.


Declare the following constant strings:

 public const string REGKEY = @"SOFTWARE\MyCompany\MyApp\"; 
public const string WINWIDTH = "windowWidth";
public const string WINHEIGHT = "windowHeight";

Then, create a key for your application in the Registry. 
Declare a RegistryKey variable:
private RegistryKey key;

Use the following method to obtain the key:

public RegistryKey GetKey(string RegKey)
{
            RegistryKey Key = Registry.CurrentUser.OpenSubKey(RegKey, true);
            if (Key == null)
            {
                Key = Registry.CurrentUser.CreateSubKey(RegKey);
            }
            return Key;
}

key =  GetKey(REGKEY);

Get window width and height:

int width = Form1.Size.Width;
int height = Form1.Size.Height;
Save window width and height in the registry and close the RegistryKey.


key.SetValue(WINWIDTH, width);
key.SetValue(WINHEIGHT, height);
key.Close(); 
When you load your form, read the values from the registry:
width = Convert.ToInt16 (key.GetValue(WINWIDTH));
height = Convert.ToInt16 (key.GetValue(WINHEIGHT));

Set the new window size:
Form1.Size = new Size(width, height);

Tuesday, July 20, 2010

Concise Code to Enable/Disable WinForm Controls

Let's say you have a check box (cb1)  on a form that enables a text box (txt1)  and disables a listbox (lst1).  You can write a statement that shows this dependency on 2 lines:

  txt1.Enabled = cb1.Checked;
  lst1.Enabled = !cb1.Checked;

This works fine. However, we repeat the reference to the check box state twice.
There is a way to write the above statements on the same line:

   lst1.Enabled = !(txt1.Enabled = cb1.Checked);

Looks simple when you get it right. But it took me a few minutes to figure it out.

Friday, July 16, 2010

Examine Columns in ASP.NET Dynamic Data MetaTable

This is how you get access to all columns in a MetaTable that serves as a data source to your controls like a DetailsView or a GridView. Dynamic Data generates the following code for each ASP.NET page by default:


   protected MetaTable table;

   protected void Page_Load(object sender, EventArgs e)
   {
       table = DetailsDataSource.GetTable();
       Title = table.DisplayName;
   }
The MetaTable class has a Columns property that returns a collection of MetaColumns for the table. This allows us to enumerate through the collection and check for any custom attributes on table columns:
    
   foreach (MetaColumn column in table.Columns)
   {
      if (column.Attributes.OfType<MyCustomAttribute>().Count() > 0)
          ......
      }
   }

This is based on a tip found at this blog.

Thursday, July 8, 2010

Reverse .NET SortedList

 This post shows how you could reverse a SortedList in C# by its keys:

SortedList<string, string> strlist = new SortedList<string, string>();
strlist.Add("f3", "xxx");
strlist.Add("f1", "ccc");
strlist.Add("f2", "aaa");

foreach (KeyValuePair<string, string> kvp in strlist)
{
    Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}           

Console.WriteLine("reverse the list");
IEnumerable<KeyValuePair<string, string>> revList = strlist.Reverse();
foreach (KeyValuePair<string, string> kvp in revList)
{
    Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}




Monday, June 7, 2010

Open a Text File If It Is Used by Another Process

Use the FileStream class's Open method to open a file with FileShare.ReadWrite as a parameter. Then use StreamReader class supplying the FileStream object as a constructor argument:
FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs);

Thursday, June 3, 2010

Set Instance Property Value through Reflection

This is how you can set object property value using reflection:

Employee emp = new Employee();
PropertyInfo pi = emp.GetType().GetProperty("myPropertyName");
pi.SetValue(emp, "myValue", null);

This is how you read a value:

string value = pi.GetValue(emp, null);

To access all properties of an object:

foreach (PropertyInfo info in emp.GetType().GetProperties()){
    ....
}
Using reflection you can automatically populate a transfer object from a database record if the object property names and types are the same as the record names and types.

An example using a DataReader:

List <employee>list = new List <employee>();
while (dataReader.Read())
{
Employee emp = new Employee();
foreach (PropertyInfo info in emp.GetType().GetProperties())
{
   if (!DBNull.Value.Equals(dr[info.Name]))
      info.SetValue(emp, dr[info.Name], null);
}
list.Add(emp);
}
 
The resulting list will hold Employee records.