<div style="width: 200px; height: 100px; overflow: auto"> <asp:GridView ID="gvGrid" runat="server"/> </div>
Tuesday, September 29, 2009
Scrollbar on a GridView
An ASP.NET GridView control will keep expanding down the page as more data is added. What if you want to control its height though? You could using Paging. You can also add scrollbars using styles. Here is an example of how you do this:
Friday, August 28, 2009
Reading from Isolated Storage
You learned how to write to Isolated Storage in the previous post. Here is how you read from it:
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly();
IsolatedStorageFileStream stream = new IsolatedStorageFileStream("pref.txt", FileMode.OpenOrCreate, isf);
StreamReader sr = new StreamReader(stream);
SetWidthAndHeight(sr.ReadToEnd());
sr.Close();
Isolated Storage
Isolated Storage - A private file system managed by the .NET Framework.
Why use it?
Isolated Storage provides a safe location, regardless of user access level, to store information that can be isolated by each user on the machine to store such things as user preferences.
How do I use it?
Here's an example where I store the height and width of a window in a text file on closing.
Where did this text file actually get saved?
Well, on my machine (Vista) it went into C:\Users\[User]\AppData\Local\IsolatedStorage and then through 3 more cryptic folder names until it reached the AssemFiles folder where the "pref.txt" file showed up.
The location can change depending on the OS. See here for other OS locations.
More Info: Article: When and when not to use Isolated Storage
Why use it?
Isolated Storage provides a safe location, regardless of user access level, to store information that can be isolated by each user on the machine to store such things as user preferences.
How do I use it?
Here's an example where I store the height and width of a window in a text file on closing.
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly();
IsolatedStorageFileStream stream = new IsolatedStorageFileStream("pref.txt", FileMode.Create, isf);
StreamWriter sw = new StreamWriter(stream);
sw.WriteLine("Width:" + this.Width);
sw.WriteLine("Height:" + this.Height);
sw.Close();
Where did this text file actually get saved?
Well, on my machine (Vista) it went into C:\Users\[User]\AppData\Local\IsolatedStorage and then through 3 more cryptic folder names until it reached the AssemFiles folder where the "pref.txt" file showed up.
The location can change depending on the OS. See here for other OS locations.
More Info: Article: When and when not to use Isolated Storage
Thursday, August 27, 2009
Reading Data from the Configuration (*.config) File
In the previous post I saved data to the config file. Here is an example of how you would read data from the config file:
More Info: MSDN: ConfigurationManager.AppSettings
if (ConfigurationManager.AppSettings["Width"] != null) { this.Width = Convert.ToDouble(ConfigurationManager.AppSettings["Width"]); } if (ConfigurationManager.AppSettings["Height"] != null) { this.Height = Convert.ToDouble(ConfigurationManager.AppSettings["Height"]); }
More Info: MSDN: ConfigurationManager.AppSettings
Saving Data to the Configuration (*.config) File
Sometimes you want to save data to the configuration file so it's available the next time the application runs. An example of this is saving a window's last height and width upon closing. Here's how you do it:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); config.AppSettings.Settings.Remove("Width"); config.AppSettings.Settings.Add("Width", this.Width.ToString()); config.AppSettings.Settings.Remove("Height"); config.AppSettings.Settings.Add("Height", this.Height.ToString()); config.Save(ConfigurationSaveMode.Modified);
Mark, why do I have to call the Remove method before adding?
Every time you call the Add method it appends data instead of overwriting it. Without calling the Remove method your configuration file will go from this:<configuration> <appSettings> <add key="Width" value="402" /> <add key="Height" value="177" /> </appSettings> </configuration>to this on the next save:
<configuration> <appSettings> <add key="Width" value="402,300" /> <add key="Height" value="177,154" /> </appSettings> </configuration>More Info: MSDN: Configuration Class
Friday, August 7, 2009
Starting another .NET program using the Application Domain Class
The AppDomain class allows you to start another .NET assembly in it's own memory space (separate from your main program's memory space). This is different from executing a process from a thread which is contained in your main program's memory space.
Here's an example of how you can do this with the .NET assembly's path:
More Info: MSDN: AppDomain Class
Here's an example of how you can do this with the .NET assembly's path:
AppDomain d = AppDomain.CreateDomain("New Domain"); d.ExecuteAssembly(@"C:\LoginToExternalApp.exe");You can't call just any exe though. It has to run within the .NET Framework runtime. So something like this won't work:
AppDomain d = AppDomain.CreateDomain("New Domain"); d.ExecuteAssembly(@"C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe");Another way to start an app is to create a reference to it and then call ExecuteAssemblyByName.
AppDomain appDomain = AppDomain.CreateDomain("New Domain"); appDomain.ExecuteAssemblyByName("LoginToExternalApp");The user may manually close the application you start up programmatically. If you need to close it down programmatically though, you can use AppDomain.Unload method:
AppDomain.Unload(d);
More Info: MSDN: AppDomain Class
Thursday, August 6, 2009
Getting data back from a thread
How do you get data back from a thread if you don't know when it'll finish running? You do it by using a delegate. When the code in the thread is complete, it'll call a delegate that is referenced back at the originating code.
Here are the basic steps:
Let's put everything together and see how it all works in this console application:
Here are the basic steps:
- Define a delegate.
- In the class that contains the method to be called, create a field/property of your new delegate.
- In the class that starts the thread, define a method that matches your delegate's signature. This is the method that will be receiving the callback from the thread.
- Instantiate the class and set your delegate to the method you created.
- Have your class call the delegate somewhere when the thread runs.
public delegate void ReturnResult(object sender);
public ReturnResult ReturnResultDelegate;
static void CheckReturnedResult(object sender) { Math m = (Math) sender; Console.WriteLine("Result:" + m.Result); }
Math math = new Math();
math.Value1 = 1;
math.Value2 = 3;
math.ReturnResultDelegate = CheckReturnedResult;
public void Add(object o) { Result = Value1 + Value2; ReturnResultDelegate(this); }
Let's put everything together and see how it all works in this console application:
using System; using System.Threading; namespace ThreadingApp { class Program { static void Main(string[] args) { Math math = new Math(); math.Value1 = 1; math.Value2 = 3; math.ReturnResultDelegate = CheckReturnedResult; ThreadPool.QueueUserWorkItem(math.Add); Thread.Sleep(1000); } static void CheckReturnedResult(object sender) { Math m = (Math)sender; Console.WriteLine("Result:" + m.Result); } } public class Math { public int Value1; public int Value2; public int Result; public delegate void ReturnResult(object sender); public ReturnResult ReturnResultDelegate; public void Add(object o) { Result = Value1 + Value2; ReturnResultDelegate(this); } } }In this sample, I minimize the scope of the delegate by including it in the class being called (Math). You might declare it outside the class if needed.
Another way to pass data into a thread
In the previous thread post I showed a way you can pass information into a thread. Here is another way in which you instantiate the class containing the method you want your thread to call first.
Math math = new Math();
math.Value1 = 1;
math.Value2 = 3;
ThreadPool.QueueUserWorkItem(math.Add);
Now when math.Add is called, it has all the information it needs to do its work.
Easiest way to start a thread
The easiest way to start a process on another thread is to call ThreadPool.QueueUserWorkItem.
Example:
More Info: MSDN: QueueUserWorkItem
Example:
// DoSomeWork is a method.
ThreadPool.QueueUserWorkItem(DoSomeWork);
Note: The DoSomeWork method has to have an Object as a parameter.
private static void DoSomeWork(object info) { // Code that does work. }If you need to pass data into your method, you can do so:
ThreadPool.QueueUserWorkItem(DoSomeWork, "Info")
You will just have to cast the object back into the appropriate data type.
private static void DoSomeWork(object info) { string workInfo = (string) info; // Code that does work. }
More Info: MSDN: QueueUserWorkItem
Wednesday, August 5, 2009
Adding Text to Images
Adding text to an image requires 2 steps:
- Create a Graphics object
- Create a Font object
- Call Graphics.DrawString method
private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; Font f = new Font("Arial", 12, FontStyle.Bold); g.DrawString("Copyright 2009", f, Brushes.Black, 10, 10); }Why would you do this? Most likely you wouldn't. You would use a label instead. But you can also draw strings on images and that is most likely what you would use this method for. More Info: MSDN: Graphics.DrawString Method
Tuesday, August 4, 2009
Assigning Images to Windows Controls
Use a Bitmap or Image class.
More Info: MSDN: Image Class
button1.BackgroundImage = new Bitmap("bm.jpg"); // or pictureBox1.BackgroundImage = Image.FromFile("bm.jpg");
More Info: MSDN: Image Class
Creating and Saving a Picture
There are 3 steps to creating and saving a picture:
- Create a Bitmap object.
- Edit it using Graphics object.
- Call Bitmap.Save method to save it.
Bitmap bm = new Bitmap(100, 100); Graphics g = Graphics.FromImage(bm); g.DrawEllipse(new Pen(Color.Red), new Rectangle(5, 5, 90, 90)); bm.Save("bm.jpg", ImageFormat.Jpeg);Here is what it looks like: If you would like to edit an existing image instead, you can use:
Bitmap bm = new Bitmap("existingImage.jpg");More Info: MSDN: Bitmap Class
Thursday, July 23, 2009
Nullable
When declaring a value type (int, bool, char, DateTime, etc.) you cannot initialize it to null or you'll get this error message:
To fix this you need to declare your variable as nullable:
More Info: MSDN: Nullable(T) Structure
Nullable<bool> answer1 = null; // or bool? answer2 = null;When this is done, 2 new properties become available to you, HasValue and Value. Now you can check if your variable has been assigned a value yet or if it's still null with HasValue.
if (answer1.HasValue) Console.WriteLine("answer1 is {0}", answer1);
More Info: MSDN: Nullable(T) Structure
Wednesday, June 24, 2009
Authenticated User Information
So you have used the built-in ASP.NET Login controls (Login, LoginView, etc). Now what if you want to get at the authenticated user information in code?
Access it through the HttpContext.Current.User property.
Examples:
More Info: MSDN: HttpContext.Current.User
Access it through the HttpContext.Current.User property.
Examples:
// Get the user's name string userName = HttpContext.Current.User.Identity.Name;
More Info: MSDN: HttpContext.Current.User
Saturday, January 17, 2009
Enum.Parse (String to Enum)
I recently wanted to convert a string held in a database to an enum. After a little digging I found Enum has a Parse method!
Since Enum doesn't have a TryParse, you should wrap it in a try-catch. More Info: MSDN:
public enum Day { Sunday = 1, Monday = 2, Tuesday = 3, Wednesday = 4, Thursday = 5, Friday = 6, Saturday = 7 } Day daysEnum = (Day) Enum.Parse(typeof (Day), "monday", true); // or even parse by number! Day daysEnum = (Day) Enum.Parse(typeof (Day), "2", true);
Since Enum doesn't have a TryParse, you should wrap it in a try-catch. More Info: MSDN:
Subscribe to:
Posts (Atom)