March 31, 2011

Using Xaml resources in a common assembly

First put the resources in a resource dictioanry xaml file that goes into the shared resource assembly. In this sample the assembly is called Common and the common resources are placed in a subdirectory WPF of this assembly. Their is no ".cs" file associated with this Xaml file. Here is the Xaml file in the "Common" assembly with a shared listbox style called "MyListStyle":
<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:System="clr-namespace:System;assembly=mscorlib">
            <Style x:Key="MyListStyle" TargetType="ListBox">
   ...
            </Style>
</ResourceDictionary>

To reference these resources in another WPF component, do it from the Resources area of the WPF component. For example
<Window ... >
    <Window.Resources>
         <ResourceDictionary Source="/Common;component/WPF/Resources.xaml" />
    </Window.Resources>
 ...
        <ListBox ... Style="{StaticResource MyListStyle}" />
 ...
</Window>

To reference those resources from a WPF Application:
<Application ... >
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Common;component/WPF/Resources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Once added to an application's resources they can be accessed anywhere in the normal fashion:
<Window ... >
...
        <ListBox ... Style="{StaticResource MyListStyle}"  />
...  
</Window>

March 11, 2011

Windows Explorer Context Menus

A simple C# function to add context menu items in Explorer
Add a context menu to the Windows Explorer

Use this quick class to add a new menu item to the context menu of folders or file extensions (although I have not tested the latter) in Windows Explorer. Modified from some of the code from the latter article. Could be expanded to add context menu items for different extensions (see first article/link).Have done this but it is not tested.
public class ExplorerContextMenuHelper
{
    private string m_MenuNameSubKey = "MenuName";
    private string m_ExtensionSubkey = "Folder";

    private string m_menuText = "";
    private string m_menuCommand = "";
    private string m_menuCommandLineArgs = "";

    // Some file extension context menu helper
    public ExplorerContextMenuHelper(
            string extension,
            string menuName,
            string menuText,
            string menuCommandLine,
            string menuCommandLineArgs)
        : this(menuName, menuText, menuCommandLine, menuCommandLineArgs)
    {
        Debug.Assert(!string.IsNullOrEmpty(extension));
        m_ExtensionSubkey = extension;
    }

    // Folder context menu helper
    public ExplorerContextMenuHelper(
        string menuName,
        string menuText,
        string menuCommandLine,
        string menuCommandLineArgs)
        : this(menuName, menuText, menuCommandLine)
    {
        Debug.Assert(!string.IsNullOrEmpty(menuCommandLineArgs));
        m_menuCommandLineArgs = menuCommandLineArgs;
    }

    public ExplorerContextMenuHelper(
        string menuName,
        string menuText,
        string menuCommandLine)
    {
        Debug.Assert(!string.IsNullOrEmpty(menuName));
        Debug.Assert(!string.IsNullOrEmpty(menuText));
        Debug.Assert(!string.IsNullOrEmpty(menuCommandLine));
        m_menuText = menuText;
        m_menuCommand = menuCommandLine;
        m_MenuNameSubKey = menuName;
    }


    public ExplorerContextMenuHelper(string menuName)
    {
        Debug.Assert(!string.IsNullOrEmpty(menuName));
        m_MenuNameSubKey = menuName;
    }


    public string ExtensionMenuNameSubKey
    {
        get { return m_ExtensionSubkey + "\\shell\\" + m_MenuNameSubKey; }
    }

    public string ExtensionMenuCommandSubkey
    {
        get { return ExtensionMenuNameSubKey + "\\command"; }
    }

    public string MenuCommand
    {
        get { return m_menuCommand + " " + m_menuCommandLineArgs; }
    }

    public void CheckSecurity()
    {

        //check registry permissions
        RegistryPermission regPerm;
        regPerm = new RegistryPermission(RegistryPermissionAccess.Write,
                    "HKEY_CLASSES_ROOT\\" + ExtensionMenuNameSubKey);
        regPerm.AddPathList(RegistryPermissionAccess.Write,
                    "HKEY_CLASSES_ROOT\\" + ExtensionMenuCommandSubkey);
        regPerm.Demand();

    }

    public bool TryAddMenuItem()
    {
        bool res = false;
        try
        {
            CheckSecurity();
            using (RegistryKey regmenu = Registry.ClassesRoot.
                    CreateSubKey(ExtensionMenuNameSubKey))
            {
                regmenu.SetValue("", m_menuText);
            }
            using (RegistryKey regcmd = Registry.ClassesRoot.
                    CreateSubKey(ExtensionMenuCommandSubkey))
            {
                regcmd.SetValue("", MenuCommand);
            }
            res = true;
        }
        catch (Exception ex)
        {
            LogException(ex.ToString());
        }
        return res;
    }

    public void TryRemoveMenuItem()
    {
        try
        {
            CheckSecurity();
            Registry.ClassesRoot.DeleteSubKey(ExtensionMenuCommandSubkey, false);
            Registry.ClassesRoot.DeleteSubKey(ExtensionMenuNameSubKey, false);
        }
        catch (SecurityException sex)
        {
            LogException(sex.ToString());
        }
        catch (UnauthorizedAccessException uae)
        {
            LogException(uae.ToString());
        }
    }

    private void LogException(string error)
    {
        Debug.WriteLine(error);
    }
}
Here some sample code that uses it:
private void RegisterWithExplorer()
{
  string path = new Uri(Assembly.GetExecutingAssembly().
                        GetName().CodeBase).LocalPath;
  ExplorerContextMenuHelper ecm = new ExplorerContextMenuHelper(
               "PhotoBackupApp", "Backup photos", path, "\"%1\"");
  ecm.TryAddMenuItem();
}

private void UnregisterWithExplorer()
{
  ExplorerContextMenuHelper ecm = new ExplorerContextMenuHelper(
                                                "PhotoBackupApp");
  ecm.TryRemoveMenuItem();
}

March 4, 2011

Immediate/Lazy Execution Terms

Deferred execution and eager evaluation

Immediate Execution - means that the computation/execution is done in the function and finished once the function return. (Fully eager evaluation as most C# code does)
Deferred/Eager Execution (buffering) - means that most of the work will be done on the first MoveNext() or when the IEnumerator instance is created (For IEnumerable it is when GetEnumerator is called)
Deferred/Lazy Exceution (streaming) - means that the work will be done each time GetNext() is called but nothing before.

March 1, 2011

Filtering a Multiline string Line by Line using a Regular Expression

For other regular expression stuff see also this blog
This routine filters a string containing multiple lines using the supplied regular expression filter. Set the invert parameter to true if you want the results inverted
private string Filter(string reportText, string regExFilter, bool invert)
{
    if (regExFilter.Length > 0)
    {
        StringBuilder output = new StringBuilder();
        string[] lines = reportText.Split(
          new string[] { Environment.NewLine }, 
          StringSplitOptions.None);
        foreach (string line in lines)
        {
            if ((line.Length > 0))
            {
                bool matches = Regex.IsMatch(line, regExFilter,
                                             RegexOptions.None);
                if ((matches && !invert) || (!matches && invert))
                    output.AppendLine(line);
            }
        }
        return output.ToString();
    }
    else
    {
        return reportText;
    }
}

February 22, 2011

String Class Extensions

string.Right() method and case insensisitive IndexOf
String Extension Collection for C#
Favorite String Extension Methods in C#

Convert 'string.Right()' to an extension method
static class StringExtensions
{
  static string Right(this string s, int count )
  {
    string newString = String.Empty;
    if (s != null && count > 0)
    {
      int startIndex = s.Length - count;
      if (startIndex > 0)
        newString = s.Substring( startIndex, count );
      else
        newString = s;
    }
    return newString;
  }
}

February 15, 2011

Method to Retrieve a Web Page as A String

Here is some sample code for this:
/// <summary>
/// Synchronously reads the contents of a url and returns it as a string
/// </summary>
/// <param name="url">Url to read</param>
/// <param name="requestOK">Whether the request succeeded of failed</param>
/// <param name="msg">Error message when something went wrong</param>
/// <returns>url contents as a string</returns>
public string TryGetUrlContents(string url, out bool requestOK, out string msg)
{
    string webPage = string.Empty;
    WebRequest webRequest = null;
    requestOK = true;
    msg = "No response to the web request";
    try
    {
        webRequest = WebRequest.Create(url);
        //webRequest.Method = "GET"; // Not necessary, it is GET by default                
        requestOK = (webRequest != null);
    
        if (requestOK)
        {
            using (WebResponse response = webRequest.GetResponse())
            {
                // tries to load as a UTF-8 document by default
                // true parameter here tells it to try and work out 
                // the document format if it is not UTF-8
                using (StreamReader responseStream = new 
                       StreamReader(response.GetResponseStream(), true))
                {
                    webPage = responseStream.ReadToEnd();
                    msg = "";
                }
            }
        }
    }
    catch (WebException we)
    {
        HandleException(we);
        msg = "Exception caught tring to make the request:" + we.ToString();
        requestOK = false;
    }

    return webPage;
}

void HandleException(Exception ex)
{
    Debug.WriteLine("Exception caught: " + ex.ToString());   
}
It has been changed to attempt to encode the returned contents correctly. If you do not care whether the retrieval worked correctly or not then use this:
public string TryGetUrlContents(string url)
{
    bool requestOK;
    string msg;
    return TryGetUrlContents(url, out requestOK, out msg);
}

WPF Databinding to User Settings

Used this website as a reference: Binding to User Settings in WPF

In the Xaml add
xmlns:Properties="clr-namespace:XXX.Properties"
to the window/control attributes section where XXX is the application namespace under which the properties are defined

Then to bind a setting
Text="{Binding Source={x:Static Properties:Settings.Default}, Path=SomeSetting, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

Note without the 'UpdateSourceTrigger' definition the updating did not work when the update was made programmatically. By default the 'UpdateSourceTrigger' is set to 'FocusChanged' so that only when the control lost it's focus would the change be passed on back to the source.
Why this change worked