Archive for the ‘csharp’ Category.

How to upload a file to an FTP server using C#?

C# (Mono) on FreeBSD

Ok, so today I needed to FTP a file.  It took me some time and research but I have a function that will upload a file to an FTP server.

I found a lot of examples that were very complex, and rightfully so as they have a lot of error and exception handling. However, this complexity makes it difficult to learn.

So this is a non-complex version. It follows some basic steps:

  1. Get the local file name: C:\Users\Rhyous\Desktop\File1.zip
  2. Open a request using the full destination ftp path: Ftp://Ftp.Server.tld/Path/File1.zip
  3. Configure the connection request
  4. Create a stream from the file
  5. Read the file into the a local stream
  6. Close the local stream
  7. Create a stream to the FTP server
  8. Write the local stream to the FTP stream
  9. Close the stream to the FTP server
using System;
using System.IO;
using System.Net;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
			string ftplocation = "ftp://ftp.server.tld/path";
			string file = @"C:\Users\Rhyous\Desktop\File1.zip" // Or on FreeBSD: "/usr/home/jared/test2.txt";
			string user = "Anonymous";
			string password = "AnyPasswd!";
            UploadToFTP(ftplocation, file, user, password);
        }

        static void UploadToFTP(String inFTPServerAndPath, String inFullPathToLocalFile, String inUsername, String inPassword)
        {
            // Get the local file name: C:\Users\Rhyous\Desktop\File1.zip
            // and get just the filename: File1.zip. This is so we can add it
            // to the full URI.
            String filename = Path.GetFileName(inFullPathToLocalFile);

            // Open a request using the full URI, c/file.ext
            FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(inFTPServerAndPath + "/" + filename);

            // Configure the connection request
            request.Method = WebRequestMethods.Ftp.UploadFile;
            request.Credentials = new NetworkCredential(inUsername, inPassword);
            request.UsePassive = true;
            request.UseBinary = true;
            request.KeepAlive = false;

            // Create a stream from the file
            FileStream stream = File.OpenRead(inFullPathToLocalFile);
            byte[] buffer = new byte[stream.Length];

            // Read the file into the a local stream
            stream.Read(buffer, 0, buffer.Length);

            // Close the local stream
            stream.Close();

            // Create a stream to the FTP server
            Stream reqStream = request.GetRequestStream();

            // Write the local stream to the FTP stream
            // 2 bytes at a time
            int offset = 0;
            int chunk = (buffer.Length > 2048) ? 2048 : buffer.Length;
            while (offset < buffer.Length)
            {
                reqStream.Write(buffer, offset, chunk);
                offset += chunk;
                chunk = (buffer.Length - offset < chunk) ? (buffer.Length - offset) : chunk;
            }
            // Close the stream to the FTP server
            reqStream.Close();
        }
    }
}

This works well for most files.

One problem is that this code reads the entire local file into memory, which might not be a good idea for a file that is very large (multiple gigabytes). It would be better to read the local file in bits. I upload in bits so this would not be hard to read a little bit, upload it, read a little bit more, upload it, etc…

Resources:
http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx
http://msdn.microsoft.com/en-us/library/system.io.stream.aspx
http://www.vcskicks.com/csharp_ftp_upload.php

A WPF Progress Bar

UPDATE: It turns out it would have been easier to use BackgroundWorker and MVVM so I wrote a post on doing that.A Progress Bar using WPF’s ProgressBar Control, BackgroundWorker, and MVVM

… original post below …

Today I needed a progress bar for as I was creating a c# tool that FTPs a file.  I wanted to show progress as the FTP file was uploaded.

I found a good solution at Mikes Code Blog. He has a post and a follow-up post.

WPF Progress Bar code

I created the progress bar as described and it worked. Here is a screen shot:

Thanks Mike!

Tutorial – Binding one element property to another

The properties of WPF elements can be bound to properties of other WPF Elements. Lets do some simple examples of binding one element to another.

For this tutorial, I assume you are in Visual Studio 2008.  I assume that you already know how to create a new Project and choose WPF Application.  All examples assume you have a new WPF Application.

I am the believer that one example isn’t enough, so I am going to give you three examples:

Example 1 – Binding and Element’s property to CheckBox.IsChecked

This example will demonstrate binding a Button‘s IsEnabled property to a CheckBox‘s IsChecked property.

Step 1 – Add the elements

  1. Add two items from the Toolbox:
    • CheckBox
    • Button

    The Button is named button1 and the CheckBox is named checkBox1.

  2. Change the text of the checkBox1 to “Enable button”.  This can be done either in the Properties or in the XAML.

Step 2 – Adding Binding to the Button

  1. In the XAML, locate the button1 element.
  2. Add the following to the button1 element:IsEnabled="{Binding ElementName=checkBox1, Path=IsChecked}"In your project, ElementName could be any item. In this example, we only have two elements so far: button1, and checkBox1.The XAML now looks like this (only two new lines exist):
    <Window x:Class="BindingATextBoxToASlider.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <Button Content="Button" Height="23" Margin="12,34,416,0" Name="button1" VerticalAlignment="Top" Width="75" IsEnabled="{Binding ElementName=checkBox1, Path=IsChecked}"/>
            <CheckBox Content="CheckBox" Height="16" Margin="12,12,408,0" Name="checkBox1" VerticalAlignment="Top" />
        </Grid>
    </Window>
    
  3. Compile and run your program.
  4. Check and uncheck the box an watch the binding do its work as it enables and disables the button.

Ok, so that was pretty cool. We have a simple example of binding one Element to another.

You can shoot yourself in the foot or Don’t be stupid!

Yes, you can shoot yourself in the foot by doing something stupid.

You could bind an element to itself. Let’s try it just so you can see it happen.

Add the same binding you added to button1 to checkBox1.

Compile and see what happens.

Example 2 – Binding and Element’s property to Slider.Value

This example uses a Slider and a TextBox.

Step 1 – Add the elements

  1. Add two items from the Toolbox:
    • TextBox
    • Slider

    The Slider is named slider1 and the TextBox is named textBox1.

Step 2 – Adding Binding to the TextBox

  1. In the XAML, locate the textBox1 element.
  2. Add the following to the textBox1 element:Text="{Binding ElementName=slider1, Path=Value}"ElementName can be any item. In this example, we only have two elements so far: slider1, and textBox1.The XAML now looks like this (only two new lines exist):
    <Window x:Class="BindingATextBoxToASlider.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
        <Grid>
           <TextBox Height="23" Margin="79,62,99,0" Name="textBox1" VerticalAlignment="Top" Text="{Binding ElementName=slider1, Path=Value}"/>
            <Slider Height="22" Margin="79,34,99,0" Name="slider1" VerticalAlignment="Top" />
        </Grid>
    </Window>
    
  3. Compile and run your program.
  4. Slide the slider and watch the binding do its work as its value is displayed in the textBox1 as it changes.

Calculations in XAML Bindings are Unsupported

Ok, so maybe you want to try to do calculations in the XAML Binding. It doesn’t work.

You can enter this and while it will compile, the Binding won’t work:

Text="{Binding ElementName=slider1, Path=(int)Value}"

You can enter this and while it will compile, the Binding won’t work:

Text="{Binding ElementName=slider1, Path=Value + 1}"

Example 3 – Binding and Element’s property to CheckBox.IsChecked

Ok, lets do a slight more complex example. We are going to have more than two elements. We are going to have a ListBox that contains a list of items (ListBoxItems). We are going to have a TextBox that displays the content of the selected item.

Step 1 – Add the elements

  1. Add two items from the Toolbox:
    • TextBox
    • ListBox
  2. Add multiple items to listBox1. This can be done either in the XAML or by clicking on the button for Items in the Properties of the listBox1.

Step 2 – Adding Binding to the TextBox

  1. In the XAML, locate the textBox1 element.
  2. Add the following to the textBox1 element:Text="{Binding ElementName=listBox1, Path=SelectedItem.Content}"Notice that we are using a property of a property for the Path. This is allowed. SelectedItem is a property of listBox1, and Content is a property of SelectedItem.The XAML now looks like this (only two new lines exist):
    <Window x:Class="BindingATextBoxToAListBoxSelectedItem.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <TextBox Height="23" Margin="12,23,12,0" Name="textBox1" VerticalAlignment="Top" Text="{Binding ElementName=listBox1, Path=SelectedItem.Content}"/>
            <ListBox Margin="12,52,12,110" Name="listBox1">
                <ListBoxItem>c:</ListBoxItem>
                <ListBoxItem>d:</ListBoxItem>
                <ListBoxItem>e:</ListBoxItem>
                <ListBoxItem>f:</ListBoxItem>
                <ListBoxItem>g:</ListBoxItem>
                <ListBoxItem>h:</ListBoxItem>
            </ListBox>
        </Grid>
    </Window>
    
  3. Compile and run your program.
  4. Select different items in the list and watch the textBox1 change to display the content of the selected item.

Copyright ® Rhyous.com – Linking to this post is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.

WPF Data Binding Tutorial

Introduction

This document assumes that you understand the concepts of object oriented programming and more specifically with C# programming, such as Classes or Objects, Methods, Properties, Events, etc. If not, it will be much harder to follow along.

This tutorial will cover the basics of data Binding in a WPF application. When you are done with this tutorial, you should be able to create a basic WPF-based graphical program that uses Binding. We will cover the different types of data Binding as well as what works and sometimes what doesn’t.

What is data Binding?

The idea of data Binding is to link a variable of any Type (int, string, object, etc…) to a graphical object’s Property that has the same type.

For example, lets say you have a Button object called myButton in your GUI like this: . The words “Click Me!” is a string property in the Button object: myButton.Text.

Imagine you have a string variable called strProperty in some part of your code that on its own has no way to interact with your GUI code. Lets say you want to change the myButton.Text property to match that string variable. Binding allows the button’s text string to always match a string property in some other object not really related to your GUI so if you change strProperty to equal “Enable” your button text will look like . If you then change the strProperty to “Disable” the button text will automatically change to be without out your back end code having to make any interaction with the GUI on its own.

Without Binding, you would have to write code yourself that would interact with the GUI and update the myButton.Text property when ever you update the string in code. In order to do this without Binding, you would also have to intermingle your background code with your GUI code. This can make it difficult to update or modify your GUI because GUI code is strung throughout all parts of your application. You don’t just have to update your GUI, you have to update all your code that interacts with the GUI.

So Binding allows you to have a back end code that is independent of the GUI. This is especially useful when the GUI needs to be updated or improved or when multiple GUIs exists (skins) and you can switch between them.

There are programming styles associated with developing a GUI separate from the back-end. Two of which are Model-View-Control (MVC) or Model-View-ViewModel (MVVM). This tutorial is not going to cover these, however, it is probably wise for you become familiar with these.

However, there is no reason you are limited to Binding to back end code. You can bind to code that is in the WPF GUI and very powerful applications can be written with little to no back end code.

Requirements for data Binding in WPF

In order to using data Binding, you should have the following requirements:

  1. Your project should be a WPF Application, or your project should include a WPF Window or WPF Control.
  2. Objects your elements bind to should implement System.ComponentModel.INotifyPropertyChanged.

Types of data Binding and resources

There is are multiple types of Binding. Elements bind to some type of resource and there are multiple types of resources. Static and Dynamic resource binding which uses the StaticResource Markup Extension or the DynamicResource Markup Extension.

The Binding source can also be “any public property, including properties of other controls, common language runtime (CLR) objects, XAML elements, ADO.NET DataSets, XML Fragments, and so forth.” (Reference: http://msdn.microsoft.com/en-us/magazine/cc163299.aspx).

Go to next: 1.1 Binding one element property to another


Copyright ® Rhyous.com – Linking to this page is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.

How to add a dynamic image and/or a dynamic button to a DataGrid row using a DataGridTemplateColumn and a DataTemplateSelector?

How to add a dynamic image and/or a dynamic button to a row using WPFToolKit DataGrid and DataGridTemplateColumns?

To start, I have a WPF project in Visual Studio 2008. I have installed the WPFToolKit and have added a reference to it in my project.

Often you want to display a DataGrid, but you don’t want to simply display it as is, you want to be able to enhance it and add functionality to it, such as adding an image to the start of each row or adding a button on each row.

Ok, so I have a table created using a DataTable that looks as follows:

IntVal StrVal
0 normal
1 warning
2 error

I am passing this to a WFPToolKit DataGrid.

As I pass this to a Datagrid I want to add two columns:

  1. I want to add an image that is different if it is normal, warning, or error.
  2. I want to add a button only if it is warning or error.

So the visual would look as follows:

Image IntVal StrVal Action
0 normal
1 warning
2 error

Step 1. Install prerequisites: Install Visual Studio 2008, and download and install the WPFToolkit.

You probably already have this done, and there are no steps for provided for these.

Step 2. Create a new WPF project in Visual studio 2008 and design the WPF interface

So once my project was created and the reference to WPFToolKit added, I then changed the XAML on my default Window1 class.

  1. I needed to add a reference to the toolkit here as well.
  2. I needed to add resources for my button.
  3. I needed to add three separate resources for my images.
  4. I needed to add a DataGrid.

Window1.xaml

<Window x:Class="DataGridAddButtonAndImageColumns.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wpftk="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <DataTemplate x:Key="FixThisTemplate">
            <Button Name="mButtonFixThis" Click="ButtonFixThis_Click">Fix This</Button>
        </DataTemplate>
        <DataTemplate x:Key="NormalTemplate">
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateNormal" x:Name="mNormalImage">
            <Image Width="16" Height="16" Source="C:\Users\jbarneck\Documents\QuickTests\DataGridAddButtonAndImageColumns\DataGridAddButtonAndImageColumns\bin\Debug\Normal.png" />
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateWarning" x:Name="mWarningImage">
            <Image Width="16" Height="16" Source="C:\Users\jbarneck\Documents\QuickTests\DataGridAddButtonAndImageColumns\DataGridAddButtonAndImageColumns\bin\Debug\Warning.png" />
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateError" x:Name="mErrorImage">
            <Image Width="16" Height="16" Source="C:\Users\jbarneck\Documents\QuickTests\DataGridAddButtonAndImageColumns\DataGridAddButtonAndImageColumns\bin\Debug\Error.png" />
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <wpftk:DataGrid Name="mDataGrid" ItemsSource="{Binding}" CanUserAddRows="False" IsReadOnly="True"></wpftk:DataGrid>
    </Grid>
</Window>

Step 3 – Create the data

The data can come from anywhere but for this basic example, I am just statically creating a DataTable in the Constructor.  I also added a property for the DataTable and the DataTable.DefaultView.

Data.cs

using System.Data;

namespace DataGridAddButtonAndImageColumns
{
    public class Data
    {
        #region Member Variables
        private DataTable mTable;
        #endregion

        #region Constructors

        /*
		 * The default constructor
 		 */
        public Data()
        {
            mTable = new DataTable();
            mTable.Columns.Add("IntVal", typeof(int));
            mTable.Columns.Add("StrVal", typeof(string));
            DataRow row0 = mTable.NewRow();
            row0["IntVal"] = 0;
            row0["StrVal"] = "normal";
            mTable.Rows.Add(row0);

            DataRow row1 = mTable.NewRow();
            row1["IntVal"] = 1;
            row1["StrVal"] = "warning";
            mTable.Rows.Add(row1);

            DataRow row2 = mTable.NewRow();
            row2["IntVal"] = 2;
            row2["StrVal"] = "error";
            mTable.Rows.Add(row2);

        }

        #endregion

        #region Properties
        public DataTable Table
        {
            get { return mTable; }
            set { mTable = value; }
        }

        public DataView View
        {
            get { return mTable.DefaultView; }
        }
        #endregion

        #region Functions
        #endregion

        #region Enums
        #endregion
    }
}

Step 4 – Create a ViewModel that implements INotifyPropertyChanged.

So creating a ViewModel is not exactly required but there really is benefit to the Model-View-ViewModel design pattern, so I will attempt to follow it even though this is a simple example application.

  1. I created a new object called DataViewModel.
  2. I implemented the INotifyPropertyChanged interface (though for this small application it isn’t used, I don’t want to leave it out cause you might need it for your application.)
  3. I changed the constructor to take the Data object I designed in the previous step.
  4. I expose the Table and the Table’s view as properties.

DataViewModel.cs

using System;
using System.ComponentModel;
using System.Data;

namespace DataGridAddButtonAndImageColumns
{
    public class DataViewModel : INotifyPropertyChanged
    {
        #region Member Variables
        readonly Data mData;
        #endregion

        #region Constructors

        /*
		 * The default constructor
 		 */
        public DataViewModel(Data inData)
        {
            mData = inData;
        }

        #endregion

        #region Properties
        public DataView View
        {
            get { return mData.View; }
        }

        public DataTable Table
        {
            get { return mData.Table; }
        }
        #endregion

        #region Functions

        #endregion

        #region Enums
        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}

Step 5 – Add code to pass the DataTable to the DataGrid

So in the Window1.xaml.cs file, I create a new DataViewModel object and pass it a new Data object.  I then assign the DataTable to the DataGrid’s DataContext object. My class now looks as follows.

Window1.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace DataGridAddButtonAndImageColumns
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {

        #region Member Variables
        #endregion

        #region Contructor
        public Window1()
        {
            InitializeComponent();
            DataViewModel model = new DataViewModel(new Data());

            // It is ok to pass either the DataTable or the DataView
            // so both lines below work, however I am only using one:
            //
            // mDataGrid.DataContext = model.View;
            // mDataGrid.DataContext = model.Table;

            mDataGrid.DataContext = model.Table;
        }
        #endregion

        #region Functions
        private void ButtonFixThis_Click(object sender, RoutedEventArgs e)
        {
            // Do something here
        }
        #endregion

        #region Properties
        #endregion
    }
}

Now I can compile and run see my simple DataGrid.

IntVal StrVal
0 normal
1 warning
2 error

Step 6 – Create the DataTemplateSelectors

I am going to use two DataTemplateSelector and I want them to share a base class, so first, I am going to create a base class for them.

  1. I inherit DataTemplateSelector.
  2. I add a function to find the parent Window1 object.

BaseDataTemplateSelector.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace DataGridAddButtonAndImageColumns
{
    public class BaseDataTemplateSelector : DataTemplateSelector
    {
        #region Member Variables
        #endregion

        #region Constructors
        /*
		 * The default constructor
 		 */
        public BaseDataTemplateSelector()
        {
        }
        #endregion

        #region Properties
        #endregion

        #region Functions
        protected Window1 GetWindow1(DependencyObject inContainer)
        {
            DependencyObject c = inContainer;
            while (true)
            {
                DependencyObject p = VisualTreeHelper.GetParent(c);

                if (c is Window1)
                {
                    //mSectionControl = c;
                    return c as Window1;
                }
                else
                {
                    c = p;
                }
            }
        }
        #endregion
    }
}

Now I create an ActionDataTemplateSelector and a StatusImageDataTemplateSelector.

The ActionDataTemplateSelector will overload the SelectTemplate function and correctly select the Fix button resource if the status is warning or error.

ActionDataTemplateSelector.cs

using System.Data;
using System.Windows;

namespace DataGridAddButtonAndImageColumns
{
    public class ActionDataTemplateSelector : BaseDataTemplateSelector
    {
        #region Constructors
        /*
		 * The default constructor
 		 */
        public ActionDataTemplateSelector()
        {
        }
        #endregion

        #region Functions
        public override DataTemplate SelectTemplate(object inItem, DependencyObject inContainer)
        {
            DataRowView row = inItem as DataRowView;

            if (row != null)
            {
                Window1 w = GetWindow1(inContainer);
                if (row.DataView.Table.Columns.Contains("IntVal"))
                {
                    if ((int)row["IntVal"] > 0)
                    {
                        return (DataTemplate)w.FindResource("FixThisTemplate");
                    }
                }
                return (DataTemplate)w.FindResource("NormalTemplate");
            }
            return null;
        }
        #endregion
    }
}

The StatusImageDataTemplateSelector also overloads the SelectTempate function and selects the correct image for the status.

StatusImageDataTemplateSelector .cs

using System.Data;
using System.Windows;

namespace DataGridAddButtonAndImageColumns
{
    public class StatusImageDataTemplateSelector : BaseDataTemplateSelector
    {
        #region Constructors

        /*
		 * The default constructor
 		 */
        public StatusImageDataTemplateSelector()
        {
        }
        #endregion

        #region Functions
        public override DataTemplate SelectTemplate(object inItem, DependencyObject inContainer)
        {
            DataRowView row = inItem as DataRowView;

            if (row != null)
            {
                if (row.DataView.Table.Columns.Contains("IntVal"))
                {
                    Window1 w = GetWindow1(inContainer);
                    int status = (int)row["IntVal"];
                    if (status == 0)
                    {
                        return (DataTemplate)w.FindResource("StatusTemplateNormal");
                    }
                    if (status == 1)
                    {
                        return (DataTemplate)w.FindResource("StatusTemplateWarning");
                    }
                    if (status == 2)
                    {
                        return (DataTemplate)w.FindResource("StatusTemplateError");
                    }
                }
            }
            return null;
        }
        #endregion
    }
}

Step 7 – Create functions that add the new columns and have the constructor call each function.

Each function must:

  1. Create a new DataGridTemplateColumn.
  2. Assign a string for the Header.
  3. Create a new DataTemplateSelector and assign it to the DataGridTemplateColumn’s CellTemplateSelector.
  4. Add the new DataGridTemplateColumn to the DataGrid.
        public void CreateActionButtonColumn()
        {
            DataGridTemplateColumn actionColumn = new DataGridTemplateColumn { CanUserReorder = false, Width = 85, CanUserSort = true };
            actionColumn.Header = "Action";
            actionColumn.CellTemplateSelector = new ActionDataTemplateSelector();
            mDataGrid.Columns.Add(actionColumn);
        }

        public void CreateStatusColumnWithImages()
        {
            DataGridTemplateColumn statusImageColumn = new DataGridTemplateColumn { CanUserReorder = false, Width = 85, CanUserSort = false };;
            statusImageColumn.Header = "Image";
            statusImageColumn.CellTemplateSelector = new StatusImageDataTemplateSelector();
            mDataGrid.Columns.Insert(0, statusImageColumn);
        }

Don’t forget to call the functions in the constructor.

        public Window1()
        {
            InitializeComponent();
            DataViewModel model = new DataViewModel(new Data());

            // It is ok to pass either the DataTable or the DataView
            // so both lines below work, however I am only using one:
            //
            // mDataGrid.DataContext = model.View;
            // mDataGrid.DataContext = model.Table;

            mDataGrid.DataContext = model.Table;
            CreateActionButtonColumn();
            CreateStatusColumnWithImages();
        }

Ok, so now you are finished. This should be working for you if you compile and run the program.

Image IntVal StrVal Action
0 normal
1 warning
2 error

Options for handling the images without using a static path

The images were called statically in the above example, however, that will be problematic in actual implementation as each program is installed in a different location and the install location can usually be chosen by a user. You have two options to resolve this, and I will show you how to do both:

  1. Embedding your images
  2. Using image files located in a relative path

Either option work.  The second option makes branding a little easier as code doesn’t have to be recompiled with new images to change the images, because the image files can simply be replaced.

Embedding your images
So you can embed your images as resources and use the embedded resources instead. To embed them, do this:

  1. In Visual Studio under your project, create a folder called Images.
  2. Copy your images into that folder.
  3. In the XAML, change each of the image resource lines as shown
            <Image Width="16" Height="16" Source="Images\Warning.png" />

Using image files located in a relative path
I decided to NOT embed my images but instead solve this by using a relative path. My preference is for the images to come from actual files in an images directory that is relative to the directory from which the executable is launched:

\MyFolder\
\MyFolder\program.exe
\MyFolder\Images\
\MyFolder\Images\Normal.png
\MyFolder\Images\Warning.png
\MyFolder\Images\Error.png

So in order to use relative paths, I found that I could create another object that inherits IValueConverter.

Here is what I had to do to create this:

  1. Create a new class called PathConverter.
  2. Make it inherit IValueConverter
  3. Implement the IValueConverter interface.
  4. Add code to the Convert function.
  5. Cast the “value” parameter to a DataRowView as each DataRow will be the calling object that is passed in as “value”.
  6. Get the relative path using System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location).
  7. Get the status value from the DataRowView and add a couple of if statements that return the relative + the image file path.
using System;
using System.Data;
using System.Globalization;
using System.Windows.Data;

namespace DataGridAddButtonAndImageColumns
{
    public class PathConverter : IValueConverter
    {
        #region Constructors
        /*
		 * The default constructor
 		 */
        public PathConverter()
        {
        }
        #endregion

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            DataRowView row = value as DataRowView;
            if (row != null)
            {
                if (row.DataView.Table.Columns.Contains("IntVal"))
                {
                    String workingDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                    int status = (int)row["IntVal"];
                    if (status == 0)
                    {
                        return workingDirectory + @"Images\Normal.png";
                    }
                    if (status == 1)
                    {
                        return workingDirectory + @"Images\Warning.png";
                    }
                    if (status == 2)
                    {
                        return workingDirectory + @"Images\Error.png";
                    }
                }
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new System.NotImplementedException();
        }
        #endregion
    }
}

Ok, I am not done yet.  I now needed to edit the XAML again.  here is what we do to the XAML:

  1. I add an xmlns reference to load the local namespace.
  2. I add in the windows resources and instance of the PathConverter.
  3. I change the Image Source value to: Source=”{Binding Converter={StaticResource ImagePathConverter}}”
<Window x:Class="DataGridAddButtonAndImageColumns.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wpftk="http://schemas.microsoft.com/wpf/2008/toolkit"
    xmlns:local="clr-namespace:DataGridAddButtonAndImageColumns"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <local:PathConverter x:Key="ImagePathConverter" />
        <DataTemplate x:Key="FixThisTemplate">
            <Button Name="mButtonFixThis" Click="ButtonFixThis_Click">Fix This</Button>
        </DataTemplate>
        <DataTemplate x:Key="NormalTemplate">
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateNormal" x:Name="mNormalImage">
            <Image Width="16" Height="16" Margin="3,0" Source="{Binding Converter={StaticResource ImagePathConverter}}" />
            <!--<Image Width="16" Height="16" Source="Images\Normal.png" />--><!-- Embedded -->
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateWarning" x:Name="mWarningImage">
            <Image Width="16" Height="16" Margin="3,0" Source="{Binding Converter={StaticResource ImagePathConverter}}" />
            <!--<Image Width="16" Height="16" Source="Images\Warning.png" />--><!-- Embedded -->
        </DataTemplate>
        <DataTemplate x:Key="StatusTemplateError" x:Name="mErrorImage">
            <Image Width="16" Height="16" Margin="3,0" Source="{Binding Converter={StaticResource ImagePathConverter}}" />
            <!--<Image Width="16" Height="16" Source="Images\Error.png" />--><!-- Embedded -->
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <wpftk:DataGrid Name="mDataGrid" ItemsSource="{Binding}" CanUserAddRows="False" IsReadOnly="True"></wpftk:DataGrid>
    </Grid>
</Window>

Ok, now we should be done.

Make sure to create the Images folder and add the images in the location where you exectuable runs. You may have to add the images folder to both the debug and release directories or otherwise resolve this, else you will get an exception when the images are not found.

Note: I wrote an improved version of this article and published it here:
http://www.codeproject.com/KB/WPF/AddImageToColumnDynamicly.aspx


Copyright ® Rhyous.com – Linking to this page is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.

A status hander object that keeps the worst status

Ok, so I have an object that is to be compared to a default value and based on the comparison has a status of either normal (0), warning (1), or error (2). Of course, it has an array of child objects that each can also be normal, warning, or error. This parent object should have the status that is the worst or greatest.

So I wrote an object caled StatusHandler.cs that does this in C#. It is simple.

/*Copyright 2010 Jared Barneck All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY Jared Barneck ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are those
 * of the authors and should not be interpreted as representing official policies,
 * either expressed or implied, of Jared Barneck.
 */

namespace StatusHandler
{
    /*
     * The purpose of this class is to hold the worst result
     * received when comparing values in a multicolum row.
     */
    public class StatusHandler
    {
        #region Member Variables
        private CompareResult mResult = CompareResult.Normal;
        #endregion

        #region Constructors

        /*
		 * The default constructor
 		 */
        public StatusHandler()
        {
        }

        public StatusHandler(CompareResult inResult)
        {
            mResult = inResult;
        }

        #endregion

        #region Properties

        public CompareResult Result
        {
            get { return mResult; }
            // Don't allow setting, this should be
            // done by the AddResult function;
        }
        #endregion

        #region Functions
        /*
         *
         */
        public void AddResult(CompareResult inResult)
        {
            // Once an error, always an error
            if (Result == CompareResult.Error)
            {
                return;
            }
            // If a warning, only change the value
            // If the new value is an error.
            if (Result == CompareResult.Warning)
            {
                if (inResult == CompareResult.Error)
                {
                    mResult = inResult;
                }
                return;
            }
            // If result is not an error or warning, then
            // it is most efficient just to set the new
            // value to the incoming value.
            mResult = inResult;
        }

        /*
         * Sets the status back to normal
         */
        public void Reset()
        {
            mResult = CompareResult.Normal;
        }
        #endregion

        #region Enums
        public enum CompareResult
        {
            Normal = 0,
            Warning,
            Error
        }
        #endregion
    }
}

How to use DataTable.Select() when the DataColumn.ColumnName contains a space?

I have a DataColumn that contains an space and I just couldn’t get the DataTable.Select(“Column Name=value) function to work.

So i found a solution on some other guys wordpress blog here.

The answer should be obvious to those who use SQL. In SQL to use a space, it often adds square brackets around the column names. [Column Name]. Yes, using square brackets is the solution.

String colName = "Column Name";
String Value = "some data";
DataTable.Select("[" + colName + "]='" + value + "'");

A snippet for handling each native type in C# and Visual Studio…when generics won't work.

So sometimes you have to have a function that can do something to any native type.

Below are two snippets to speed up the coding for you.

Ok, so of course there are times when you can use Generics.

public class myclass<T>
{
	myclass(T inT)
	{
		// your class
	}
}

However, there are functions that don’t work with a generic type T.

public class myclass<T>
{
	myclass(T inT1, T inT2)
	{
		if (inT1 < inT2)
		{
			// do something
		}
	}
}
&#91;/sourcecode&#93;

This results in an error:   Error 1 Operator '<&#39; cannot be applied to operands of type &#39;T&#39; and &#39;T&#39;.

Maybe you need to handle all the native data types.  So it is annoying to type them in, so I created an iftype snippet.

Create a file called iftype.snippet in this directory: C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C#\
Copy in this source and save the file.

&#91;sourcecode language="csharp"&#93;
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>iftype</Title>
			<Shortcut>iftype</Shortcut>
			<Description>Code snippet for an automatically implemented an 'if' statement for each native type.</Description>
			<Author>Jared Barneck</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>varName</ID>
					<ToolTip>Variable name</ToolTip>
					<Default>t</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><!&#91;CDATA&#91;
				if ($varName$.Equals(typeof(bool)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Byte)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Char)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(DateTime)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Decimal)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Double)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Int16)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Int32)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Int64)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(SByte)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(Single)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(String)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(TimeSpan)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(UInt16)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(UInt32)))
                {
					throw new NotImplementedException();
                }
                else if ($varName$.Equals(typeof(UInt64)))
                {
					throw new NotImplementedException();
                }
$end$&#93;&#93;>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

However, you prefer a switch statement to an if statement. Here is the same thing using the switch statement.

Create a file called switchtype.snippet in this directory: C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC#\Snippets\1033\Visual C#\
Copy in this source and save the file.

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>switchtype</Title>
			<Shortcut>switchtype</Shortcut>
			<Description>Code snippet for an automatically implemented a switch statement for each native type.</Description>
			<Author>Jared Barneck</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>a
			<Declarations>
				<Literal>
					<ID>varName</ID>
					<ToolTip>Variable name</ToolTip>
					<Default>varName</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><!&#91;CDATA&#91;
			Type t = $varName$;
            switch (t.ToString())
            {
                case "System.Boolean":
                    throw new NotImplementedException();
                    break;
                case "System.Byte":
                    throw new NotImplementedException();
                    break;
                case "System.Char":
                    throw new NotImplementedException();
                    break;
                case "System.DateTime":
                    throw new NotImplementedException();
                    break;
                case "System.Decimal":
                    throw new NotImplementedException();
                    break;
                case "System.Double":
                    throw new NotImplementedException();
                    break;
                case "System.Int16":
                    throw new NotImplementedException();
                    break;
                case "System.Int32":
                    throw new NotImplementedException();
                    break;
                case "System.Int64":
                    throw new NotImplementedException();
                    break;
                case "System.SByte":
                    throw new NotImplementedException();
                    break;
                case "System.Single":
                    throw new NotImplementedException();
                    break;
                case "System.String":
                    throw new NotImplementedException();
                    break;
                case "System.TimeSpan":
                    throw new NotImplementedException();
                    break;
                case "System.UInt16":
                    throw new NotImplementedException();
                    break;
                case "System.UInt32":
                    throw new NotImplementedException();
                    break;
                case "System.UInt64":
                    throw new NotImplementedException();
                    break;
            }
$end$&#93;&#93;>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

What is and how do I install the Northwind database?

The Northwind database is referenced online in sample code quite often. However, this renders the sample code useless to someone who doesn’t know what Northwind is or how to use it.

The Northwind database is basically just an example database that runs under SQL Server. This database is populated with data that represents an imaginary company’s sales data. It is a very common example database for SQL Server testing and sampling.

You might be wondering, what is SQL Server (though for your sake, I hope not). Well, SQL Server is Microsoft’s database software.

How do I know if SQL is installed?
If you have Visual Studio 2008 installed, you probably have SQL Server 2008 installed and you don’t even know it.

You can go to Add / Remove Programs and look for Microsoft SQL Server.

Or you can check for the services.

Or if you aren’t good with the GUI, you can open a command prompt and run this command to see if you have the SQL services:

C:\Users\UserName> sc query state= all |findstr SQL |findstr DISPLAY_NAME

DISPLAY_NAME: SQL Server (SQLEXPRESS)
DISPLAY_NAME: SQL Active Directory Helper Service
DISPLAY_NAME: SQL Server Agent (SQLEXPRESS)
DISPLAY_NAME: SQL Server Browser
DISPLAY_NAME: SQL Server VSS Writer

If you don’t see the services ouptut, you don’t have SQL Server Express installed. If you do have it, it is installed.

SQL Server is installed, now where do I get the Northwind Database?
Well, this was a struggle even for me. All the posts say the database creation script was installed with Visual Studio, but I sure don’t have any database creation scripts installed.

So I searched the web and Microsoft’s site for a while.

I finally found this link, but not until after about an hour of searching, hopefully this saves you some time.
http://www.codeplex.com/Wikipage?ProjectName=SqlServerSamples

So as of 3/4/2010, there was not “new” Northwind database, just and old one for SQL 2000. Which is fine because that old database is what most the sample code you find will be using.

I clicked on the Download link next to SQL Server 2000 Sample DBs.
I downloaded a ZIP file.
I extracted it.
I found the instnwnd.sql script among the extracted files.

How do I use the instnwnd.sql file to install the Northwind Database
This instnwnd.sql is nothing more than SQL script that will install the Northwind database for you. Well, you basically need your SQL server to run this script file and that is it.

If you have SQL Server Management Studio, just open it up and connect to your database, then File | Open the script and run it. But maybe you don’t know what SQL Server Management Studio is, let alone how to open it.

Sound easy right.

Well, everything sounds easy to some one who knows exactly how to do it, but if you don’t now how, it doesn’t sound easy. If you are among those that are hearing about this for the first time, let me help you.

Well, every server that has SQL Server installed has a command line tool installed called sqlcmd.exe. Hey, if I give you a command line you can run it, even if you don’t know what is really going on.

So just open a command prompt and run this command:

C:\Users\UserName> sqlcmd -E -i c:\path\to\instnwnd.sql

Changed database context to ‘master’.
Changed database context to ‘Northwind’.

Ok, the database installed now what?
Well, now you have the Northwind database installed.

From here you are one your own getting whatever sample code you have to connect to this database and compile.

How to resolve the "Could not create an instance of Type" error when "Reloading the designer" in Visual Studio 2008?

So, I recently started trying to implement the application I am developing using an MVVM model.

However, I ran into this annoying problem where when I have my main window’s XAML code including this line:

            <uc_treeview:PluginTreeViewControl Margin="0,0,0,29" MinWidth="240" />

My PluginTreeViewControl object looks as follows:

using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows.Input;
using LANDesk.HealthCheck.PluginOutput;
using LANDesk.HealthCheckViewer.LoadOnDemand.Sections;

namespace LANDesk.HealthCheckViewer.LoadOnDemand.PluginTreeView
{
    public partial class PluginTreeViewControl : UserControl
    {
        //readonly GroupViewModel mGroup;

        public PluginTreeViewControl()
        {
            InitializeComponent();

            Output o = new Output();
            OutputViewModel viewModel = new OutputViewModel(o.PluginGroups);
            base.DataContext = viewModel;
        }
    }
}

So I found that the lines after the InitializeComponent() function are causing my attempts to “Reload the designer” to fail. If I comment them out, the designer reloads. Of course, then if I have to uncomment them before compiling or debugging, and comment them again, when working in the Designer.

So after a while a thought came to me that maybe their is some type of “if” statement that would be true for the designer but not for runtime. So I researched and found this: DesignerProperties.GetIsInDesignMode Method

After reading about this, I changed my code in my Constructor to this:

    public PluginTreeViewControl()
    {
        InitializeComponent();

        // This "if" block is only for Visual Studio Designer
        if (DesignerProperties.GetIsInDesignMode(this))
        {
            return;
        }
        Output o = new Output();
        OutputViewModel viewModel = new OutputViewModel(o.PluginGroups);
        base.DataContext = viewModel;
    }

And wouldn’t you know it, I have solved the issue entirely. The Designer now reloads just fine (as it doesn’t seem to error) and at run time the “if” statement is always false so the lines I need always run.

Also, the overhead of an “if (DesignerProperties.GetIsInDesignMode(this))” in inconsequential. However, I attempted to remove this overhead in Release builds as follows:

    public PluginTreeViewControl()
    {
        InitializeComponent();

        // This "if" block is only for Visual Studio Designer
        #if DEBUG
        if (DesignerProperties.GetIsInDesignMode(this))
        {
            return;
        }
        #endif
        Output o = new Output();
        OutputViewModel viewModel = new OutputViewModel(o.PluginGroups);
        base.DataContext = viewModel;
    }

Now, I don’t have a problem with my Designer. This workaround makes me super happy!

Learning the Model-View-ViewModel (MVVM) pattern for WPF and C#

So, I recently came across some information on a development style called Model-View-ViewModel or MVVM.

There is a Microsoft article written by Josh Smith about MVVM here:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

And an MSDN blog here:
http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx

Basically the idea is that you separate the code for three elements:

There is a book by Josh Smith on Advanced MVVM here:
http://joshsmithonwpf.wordpress.com/advanced-mvvm/

So I have recently become aware of this model and will learning more about this over time.

I am developing an Application at work and I will try to use the MVVM pattern.

How to process command line parameters or arguments in a WPF application?

UPDATE 10/25/2010:
Avoid using Environment.CommandLine. It appears much easier, but isn’t as robust. I learned a while ago that the command line arguments can be accessed using Environment.CommandLine. This is only different than the process below in that it is way easier and the first argument is the full path of the executable. So all this work is not exactly necessary, right? Wrong! I tried Environment.CommandLine for a while and it didn’t last. There are times when this executable is launched by another executable and the Environment.CommandLine is not set even though the other executable launched this executable with parameters. So I had to return to using the steps below anyway.


Ok, so I wanted to handle command line parameters, which is easy in every other language, however, the need for easy was overlooked in WPF. It is not obvious and you are not going to figure it out without being told how to do it.

Microsoft provides a sample here, you can look at.
http://msdn.microsoft.com/en-us/library/aa972153.aspx

I am going to walk you through creating a new WPF Project in Visual Studio 2008. Then I will walk you through handling command line parameters (arguments).

  1. Open Visual Studio 2008.
  2. Go to File | New | Project.
  3. Under Visual C#, choose WPF Application and give the project a name and then hit OK.
  4. Go to Project | ProjectName Properties (where ProjectName is the name of your project).
  5. In the Properties of you project, click on Debug.
  6. Enter three parameters intothe Command line arguments text field: Param1 Param2 Param3
  7. Close the properties window.
  8. Double-click on App.xaml to open it. It looks like this:
    <Application x:Class="ParametersForWPF.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="Window1.xaml">
        <Application.Resources>
    
        </Application.Resources>
    </Application>
    
  9. Add a carriage return after StartupUri=”Window1.xaml” and start type inside the bracket the word Startup=. As soon as you see an equals sign you will get a pop up with the words . Double-click on that. The name Application_Startup will automatically be added.
    <Application x:Class="ParametersForWPF.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="Window1.xaml"
        Startup="Application_Startup">
        <Application.Resources>
    
        </Application.Resources>
    </Application>
    

    Note: This will also automatcially update the App.xaml.cs file which originally looks as follows:

    using System.Windows;
    
    namespace ParametersForWPF
    {
        /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        public partial class App : Application
        {
        }
    }
    

    But after adding the Startup=”Application_Startup” line, a function called Application_Startup is automatically added.

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Windows;
    
    namespace ParametersForWPF
    {
        /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        public partial class App : Application
        {
    
            private void Application_Startup(object sender, StartupEventArgs e)
            {
    
            }
        }
    }
    
  10. Now we only want to work with arguments if there are some, so lets add an if statement inside the Application_Startup function as shown:
            private void Application_Startup(object sender, StartupEventArgs e)
            {
                if (e.Args.Length > 0)
                {
    
                }
            }
    
  11. Ok, so the next step is to create a public static string[] member variable to hold the arguments and assign the arguments array to it. I called my member variable mArgs. I use prefix it with m so I know it is a member variable.
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Windows;
    
    namespace ParametersForWPF
    {
        /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        public partial class App : Application
        {
            public static String[] mArgs;
    
            private void Application_Startup(object sender, StartupEventArgs e)
            {
    
                if (e.Args.Length > 0)
                {
                    mArgs= e.Args;
                }
            }
        }
    }
    
  12. Now, in order to access the data in Windows1.xaml.cs, just call the App.mArgs array in the constructor as shown.
            public Window1()
            {
                InitializeComponent();
                String[] args = App.mArgs;
    
            }
    
  13. Put a break point on the line and start with debugging and sure enough you will see your arguments properly assigned to the String[] args variable. So you now have your parameters accessible in your WPF application.Hope this helps you.

    Copyright ® Rhyous.com – Linking to this article is allowed without permission and as many as ten lines of this article can be used along with this link. Any other use of this article is allowed only by permission of Rhyous.com.

How read use an ADO.NET DataSet to read XML files designed with nested attributes?

I am working on a project that is XML driven and I am using ADO.NET DataSet functionality to make reading the XML easier. However, I ran into a problem that really just a lack of knowledge on my part.

Problem
So I have DataSet created using an XML. The XML is using Nested attributes. And I just need to know how to loop properly through the DataSet Tables and their columns.

I have the following XML.

<?xml version="1.0" encoding="utf-8" ?>
<Plugin PluginName="TestName" GroupName="Operating System Settings" Type="Single">
  <Title>Plugin 1</Title>
  <StartTime>1:57:47 PM 2/16/2010</StartTime>
  <EndTime>1:58:03 PM 2/16/2010</EndTime>
  <Description>Runs the TestName process to determine something.</Description>
  <Section SectionName="Section1">
    <Field FieldName="Field Name">
      <Value Operand="EQ">Some Correct Setting1</Value>
      <ActionPlugin Name="" Type="Link" URL="">
        <Executable>SomeAction1.exe</Executable>
        <Parameters>Param1 Param2</Parameters>
      </ActionPlugin>
    </Field>
    <Field FieldName="Field2">
      <Value Operand="RG">900</Value>
      <WarningLevel>10%</WarningLevel>
      <ErrorLevel>20%</ErrorLevel>
      <ActionPlugin Name="ActionPlugin1" Type="Link" URL="http://www.somesite.tld/some/path/file.htm" />
    </Field>
  </Section>
  <Section SectionName="Section2">
    <Field FieldName="Field1">
      <Value Operand="EQ">Some Correct Setting2</Value>
      <ActionPlugin Name="" Type="Link" URL="">
        <Executable>SomeAction2.exe</Executable>
        <Parameters>Param1 Param2</Parameters>
      </ActionPlugin>
    </Field>
    <Field FieldName="Field2">
      <Value Operand="RG">900</Value>
      <WarningLevel>10%</WarningLevel>
      <ErrorLevel>20%</ErrorLevel>
      <ActionPlugin Name="ActionPlugin1" Type="Link" URL="http://www.somesite.tld/some/path/file.htm" />
    </Field>
  </Section>
  <Section SectionName="Section3">
    <Field FieldName="Field1">
      <Value Operand="EQ">Some Correct Setting3</Value>
      <ActionPlugin Name="" Type="Link" URL="">
        <Executable>SomeAction3ds.exe</Executable>
        <Parameters>Param1 Param2</Parameters>
      </ActionPlugin>
    </Field>
    <Field FieldName="Field2">
      <Value Operand="RG">900</Value>
      <WarningLevel>10%</WarningLevel>
      <ErrorLevel>20%</ErrorLevel>
      <ActionPlugin Name="ActionPlugin1" Type="Link" URL="http://www.somesite.tld/some/path/file.htm" />
    </Field>
  </Section>
</Plugin>

So the DataSet is created with these tables (this is copied from the debugger):

– List Count = 5 System.Collections.ArrayList
+ [0] {Plugin} object {System.Data.DataTable}
+ [1] {Section} object {System.Data.DataTable}
+ [2] {Field} object {System.Data.DataTable}
+ [3] {Value} object {System.Data.DataTable}
+ [4] {ActionPlugin} object {System.Data.DataTable}

Table [1] {Section} has 3 rows.
Table [2] {Field} has 6 rows.

So the data looks like this:

Sections Table
Row 1
Row 2
Row 3

Fields Table
Row 1
Row 2
Row 3
Row 4
Row 5
Row 6

But I need to read it as follows:

Sections Table
Row 1  
Fields Table
Row 1
Row 2
Row 2  
Fields Table
Row 3
Row 4
Row 3  
Fields Table
Row 5
Row 6

So I had the code below, but for each Section Row it would loop through all six field rows, which is not what I intend.

string mFullPathToXML = "C:\My.xml";
DataSet ds;
ds.ReadXml(mFullPathToXML);

foreach (DataRow SectionRow in ds.Tables["Section"].Rows)
{
    foreach(DataRow FieldRow in ds.Tables["Field"].Rows)
    {
        // Looping through all rows, not just those that pertain to the section.
        // How to get only the two rows that belong to each Section row here?
    }
}

Solution
Well, I set out on a journey to figure this out. In a few search engines I use search phrases like:
DataSet XML Nested
DataSet XML Nested Relation
DataSet DataTable XML Nested Row
DataSet DataTable XML Nested Row

A lot of documentation on Microsoft’s site to XMLs and DataSets showed up, but nothing describing this problem/solution.

I am happy to say that with help from the MSDN Forums, the solution was found. Please read my post here:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataset/thread/2d115ba6-49be-4a5c-bf92-054626109f50

So the solutions is to use the Section_Id assigned to each row in the Sections table inside the Field table’s Select() function as shown:

foreach (DataRow sectionRow in ds.Tables["Section"].Rows)
{
	string sectionId = sectionRow["Section_Id"].ToString();
	Console.WriteLine("Section: {0}", sectionRow["SectionName"]);
	foreach (DataRow fieldRow in ds.Tables["Field"].Select("Section_Id = " + sectionId))
	{
		foreach (object item in fieldRow.ItemArray)
		{
			// Do something here
		}
	}
}

This solution works for me.

How to modify the default new class template for C# in Visual Studio 2008 or 2010?

Updated: 5/17/2010 using information aquired from here: How To: Edit Visual Studio Templates

Ok, so I don’t like the way that the default new class template in Visual Studio 2008/2010 looks. I end up typing a lot of things over and over again.

Here is what it a new class looks like:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyNameSpace
{
	class MyClass
	{
	}
}

Here is what I want it to look like:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyNameSpace
{
	public class MyClass
	{
		#region Member Variables
		#endregion

		#region Constructors

		/// <summary>
		/// The default Constructor.
		/// </summary>
		public MyClass()
      		{
		}

		#endregion

		#region Properties
		#endregion

		#region Functions
		#endregion

		#region Enums
		#endregion
	}
}

So making this change is easy to do. All you have to do is edit a text file that is compressed.

Copy the zip file file located here to the desktop:
Visual Studio 2008

  • For 64 bit: C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class.zip
  • For 32 bit: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class.zip

Visual Studio 2010

  • For 64 bit: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class.zip
  • For 32 bit: C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class.zip

Extract the zip file.

Using a text editor, open the Class.cs file.

The file will have the following text:

using System;
using System.Collections.Generic;
$if$ ($targetframeworkversion$ >= 3.5)using System.Linq;
$endif$using System.Text;

namespace $rootnamespace$
{
	class $safeitemrootname$
	{
	}
}

Change it to have this text:

using System;
using System.Collections.Generic;
$if$ ($targetframeworkversion$ >= 3.5)using System.Linq;
$endif$using System.Text;

namespace $rootnamespace$
{
	public class $safeitemrootname$
	{
		#region Member Variables
		#endregion

		#region Constructors

		/// <summary>
		/// The default Constructor.
		/// </summary>
		public $safeitemrootname$()
		{
		}

		#endregion

		#region Properties
		#endregion

		#region Functions
		#endregion

		#region Enums
		#endregion
	}
}

Save the file.

Rebuild the zip file with the new Class.cs.  Be careful to build the zip file correctly.

Copy the new zip file back here and overwrite the existing one:
Visual Studio 2008

  • For 64 bit: C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class.zip
  • For 32 bit: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class.zip

Visual Studio 2010

  • For 64 bit: C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class.zip
  • For 32 bit: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class.zip

Now, you have to rebuild the template classes.  To do this:

  1. Open a command prompt as Administrator.
  2. Change to the appropriate directory:
    Visual Studio 2008
    64-bit

    cd C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\

    32-bit

    cd C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\

    Visual Studio 2010
    64-bit

    cd C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\

    32-bit

    cd C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\
  3. Run this command:
    devenv.exe /installvstemplates

Now any new class you create will have your new format.


Copyright ® Rhyous.com – Linking to this article is allowed without permission and as many as ten lines of this article can be used along with this link. Any other use of this article is allowed only by permission of Rhyous.com.

How to get the relative path (folder the executable was launched in) as a string in C#?

Well, lets say you launch an application and you want to know the relative path.

In C# you can use the System.Reflection.Assembly.GetExecutingAssembly().Location value. I have searched through many online sites that tell different ways, and some of the more experienced C# developers say that some of the other ways are not always accurate or won’t always work, while this one should always work.

So if you make a class and add two String class variables, you can use this function to populate them: Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)


        private void GetPaths()
        {
            mExecutablePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
            mExecutableRootDirectory = System.IO.Path.GetDirectoryName(mExecutablePath);
        }

Ok, so I like to make sure any newbie can pull this off, so the whole file with it working (using a New WPF project):

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TestPath
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        DataSet mDataSet;
        String mExecutablePath;
        String mExecutableRootDirectory;

        public Window1()
        {
            GetPaths();
            InitializeComponent();
        }

        private void GetPaths()
        {
            mExecutablePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
            mExecutableRootDirectory = System.IO.Path.GetDirectoryName(mExecutablePath);
        }
    }
}