May 12, 2010

Creating A Single Instance WPF Application

Look here: Initial idea. - Did not seem to work!
How can I provide my own Main() method in my WPF application?
and here

Simplest solution found:
  1. On App.xaml build properties, set "Build Action" to Page.
  2. Add following code to "App.xml.cs" or equivalent, the "App" class source.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;

...

[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main()
{
  // Use mutex to ensure only single instance is running
  bool mutexOwnershipGranted = true;
  using (Mutex mutex = new Mutex(
    true, 
    "$SOMEUNIQUESTRING$", // Use GUID or string id here
    out mutexOwnershipGranted))
  {
    // If this is the only running instance
    if (mutexOwnershipGranted) 
    { // Then run app 
      DevHelperWpf.App app = new DevHelperWpf.App();
      app.InitializeComponent();
      app.Run();
    }
    else 
    { // Bring current running instance to the front
      Process current = Process.GetCurrentProcess();
      foreach (Process process in Process.GetProcessesByName(
          current.ProcessName))
      {
         if (process.Id != current.Id)
         {
            SetForegroundWindow(process.MainWindowHandle);
            break;
         }
      }
    }
  }
}

March 24, 2010

Environment Variables

Environment.SetEnvironmentVariable Method on MSDN provides some comprehensive samples

Use of "Environment.GetEnvironmentVariables()" Example:
...
  ShowEnvironmentVariables(EnvironmentVariableTarget.User);
  ShowEnvironmentVariables(EnvironmentVariableTarget.Machine);
  ShowEnvironmentVariables(EnvironmentVariableTarget.Process);
...
private static void ShowEnvironmentVariables(EnvironmentVariableTarget targ)
{
    IDictionary ret = Environment.GetEnvironmentVariables(targ);
    string[] keys = new string[ret.Count];
    string[] values = new string[ret.Count];
    ret.Keys.CopyTo(keys, 0);
    ret.Values.CopyTo(values, 0);

    string targStr = targ.ToString().ToUpper();
    string underlineStr = "=======";
    Debug.WriteLine(targStr);
    Debug.WriteLine(underlineStr);
    for (int ix = 0; ix < ret.Count; ix++)
    {
        Console.WriteLine(keys[ix] + " = " + values[ix]);
    }
    Debug.WriteLine("");
}
To write an Environment variable use "Environment.SetEnvironmentVariable"
// by default the environment variable is set on the "Process"
Environment.SetEnvironmentVariable("TestEnvVar", "change1");
// but can be set for the user
Environment.SetEnvironmentVariable("TestEnvVar", "andagain", EnvironmentVariableTarget.User);
// or the system (if the program is executed through an account 
// with the appropriate permissions)
Environment.SetEnvironmentVariable("TestEnvVar", "andagain", EnvironmentVariableTarget.Machine);

February 16, 2010

ZipStorer

Quick way to include Zip file functionality.
Find up to date version at http://zipstorer.codeplex.com/
The nice thing about ZipStorer is that you dont need to reference any other assemblies, you just include the class file in your project and away you go.
Quick and dirty example of using ZipStorer to compress a bunch of files:
...
saveFilePath = System.IO.Path.ChangeExtension(saveFilePath, "zip");
StringBuilder fileList = new StringBuilder();
string comment = "File changes from: " + 
                 DateTime.UtcNow.ToLongDateString() +
                 Environment.NewLine +
                 "Original path: " + rootDir;                                  
using (ZipStorer zipStore = ZipStorer.Create(saveFilePath, comment))
{
    foreach (CheckedListItem cli in listBoxFilesChanged.SelectedItems)
    {
        if (cli.FileSystemInfo.Exists)
        {
            zipStore.AddFile(ZipStorer.Compression.Deflate, // Compress
               cli.FullName,     // Full path of file to be added
               cli.RelativeName, // Stored as a relative path in zip file
               cli.FullName);    // Comment for stored file (source of the original)
            fileList.AppendLine(cli.FullName);
        }
    }
}
...

Show and ShowDialog in WPF

Show a WPF window in modal form use ShowDialog()
private void ShowXXXDialogModal()
{
    // Instantiate the dialog box
    XXXDlg dlg = new XXXDlg();

    // Configure the dialog box
    dlg.Owner = this;
    // Open the dialog box modally 
    dlg.ShowDialog();
}
Show a WPF window in modaless form (ie dont wait for the opened window to close before returning) use Show()
private void ShowXXXDialogModaless()
{
    // Instantiate the dialog box
    XXXDlg dlg = new XXXDlg();

    // Configure the dialog box
    dlg.Owner = this;
    // Open the dialog box modalessly 
    dlg.Show();
}

February 9, 2010

Dialog To Browse For A Folder

Need these refences
using System.Windows.Forms;
using System.IO;
Sample button logic
  
private void butBrowse_Click(object sender, RoutedEventArgs e)
{
  tbRootDir.Text = BrowseForFolder("Browse to root directory of source", tbRootDir.Text);
}
Browser dialog usage:
private string BrowseForFolder(string descr, string dir)
{
  using (FolderBrowserDialog fbd = new FolderBrowserDialog())
  {
    fbd.Description = descr;
    if (Directory.Exists(dir))
      fbd.SelectedPath = dir;
    if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
      if (Directory.Exists(fbd.SelectedPath))
      {
        dir = fbd.SelectedPath;
      }
    }
  }
  return dir;
}

January 27, 2010

Generic Constraints Syntax In C# (using where keyword)

On MSDN
or
Search for MSDN page with this

Takes the form:
... class SomeClass<args>
     where Args : class

Here is a list of valid constraints

where T: struct
The type argument must be a value type. Any value type except Nullable can be specified.

where T : class
The type argument must be a reference type; this applies also to any class, interface, delegate, or array type.

where T : new()
The type argument must have a public parameterless constructor. When used together with other constraints, the new() constraint must be specified last.

where T : <base class name>
The type argument must be or derive from the specified base class.

where T : <interface name>
The type argument must be or implement the specified interface. Can be more than one and the interfaces specified can be generic

where T : U
The type argument supplied for T must be or derive from the argument supplied for U.

January 22, 2010

Hosting WPF Controls In Windows Forms

Host WPF controls in a windows form control (using an ElementHost)
WPF for those who know Windows Forms (Large document)

You must add references to "WindowsBase", "WindowsFormsIntergration", "PresentationCore" and "PresentationFramework"
private ElementHost wpfCtrlHost;
private TestWpfControl testWpfCtrl;

public WindowsFormHost()
{
    InitializeComponent();
 ...
    HostWpfControl();
}

private void HostWpfControl()
{
    wpfCtrlHost = new ElementHost();
    wpfCtrlHost.Dock = DockStyle.Fill;
    this.Controls.Add(wpfCtrlHost);
    testWpfCtrl = new TestWpfControl();
    testWpfCtrl.InitializeComponent();
    wpfCtrlHost.Child = testWpfCtrl;
}