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;
    }
}