How to redirect Console and Debug output to your UI

How many times have you been in your test environment trying to understand whats happening with no debugger to call on.
I find this especially frustrating in WPF where binding errors fail silently. Log files are a drag - wouldn't it be cool if you could pipe the console/debug output to somewhere in your UI?

It turns out this is pretty easy. Console output can be redirected to a stream

You can easily subclass TextWriter to pipe the stream output to a textbox for example

            // Instantiate the writer 
            TextWriter _writer = new TextBoxStreamWriter(txtMessage); 
            // Redirect the out Console stream 
            Console.SetOut(_writer); 
            Console.WriteLine("Now redirecting console output to the text box");


    public class TextBoxStreamWriter : TextWriter
    {
        TextBox _output = null;

        public TextBoxStreamWriter(TextBox output)
        {
            _output = output;
        }

        public override void Write(char value)
        {
            base.Write(value);
            _output.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        _output.AppendText(value.ToString());
                    })
            ); // When character data is written, append it to the text box. 
        }

        public override Encoding Encoding
        {
            get { return System.Text.Encoding.UTF8; }
        }
    }

Undoing what you've done.
            StreamWriter standardOutput = new StreamWriter(Console.OpenStandardOutput());
            standardOutput.AutoFlush = true;
            Console.SetOut(standardOutput);

Redirecting debug output is even easier as it offers a lot of flexibility via tracelisteners out of the box

In this example I’m leverging the code from above to send debug output to the console and hence to my textbox

            Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
            Debug.WriteLine("Now redirecting debug output to the text box");

Unable to create the virtual directory. To access local IIS Web sites, you must install the following IIS components: IIS 6 Metabase and IIS 6 Configuration Compatibility ASP.NET

---------------------------
Microsoft Visual Studio
---------------------------
Unable to create the virtual directory. To access local IIS Web sites, you must install the following IIS components:

      IIS 6 Metabase and IIS 6 Configuration Compatibility
      ASP.NET

In addition, you must run Visual Studio in the context of an administrator account.

For more information, press F1.
---------------------------
OK  
---------------------------

I just received this error when I tried to create a new asp.net web app with vs2010/windows 7. The solution is you need to go to "Control Panel > Programs and Features > Turn Windows features on or off" and install at least the two missing components. After this is done you need to open visual studios command prompt and type "aspnet_regiis -i".

How to create a shortcut file with .NET

Unfortunately .NET doesn't have direct support for this task but luckily you can leverage Interop and the Windows Scripting Host Object Model to do this with only a few lines of code. Windows Scripting Host is an automation technology for Microsoft Windows operating systems that provides scripting capabilities comparable to batch files, but with a greater range of supported features.


Steps to get this working:

1) Add a reference to "Windows Script Host Object Model" to your project - this will be found under the COM tab in the add reference dialog.

2) Add a using to the class where your shortcut create code will go. e.g.

using IWshRuntimeLibrary;

3) Use the following code to create a shortcut. I would recommend making a helper class for this. e.g.

    WshShell shell = new WshShell();
    IWshShortcut link = (IWshShortcut)shell.CreateShortcut("c:\My Notepad Shortcut.lnk");
    link.TargetPath = "c:\windows\notepad.exe";
    link.Save();

Why doesn't my keyboard navigation work on templated ComboBoxes/ItemControls

There is a little gotcha here when you overwrite the itemcontainerstyle on an items control. If you want to allow quick access items by typing prefixes of strings you need to setup some attached properties.

There is 2 ways you can go you can either add the TextSearch.TextPath attached property on the ItemControl or add the TextSearch.Text attached property on the individual item.

Example:

<ComboBox IsEditable="true" TextSearch.TextPath="Name">
            <Image Name="Cat" Source="data\cat.png"/>
            <Image Name="Dog" Source="data\dog.png"/>
            <Image Name="Fish" Source="data\fish.png"/>
ComboBox>

<ComboBox IsEditable="true">
<Image TextSearch.Text="Cat" Source="data\cat.png"/>
            <Image TextSearch.Text="Dog" Source="data\dog.png"/>
            <Image TextSearch.Text="Fish" Source="data\fish.png"/>
ComboBox>


Example of how to do this when overwriting the itemcontainerstyle:

        <ComboBox.ItemContainerStyle>
            <Style TargetType="{x:Type ComboBoxItem}">
                <Setter Property="TextSearch.Text">
                    <Setter.Value>
                        <MultiBinding StringFormat="{} {0} {1}">
                            <Binding Path="FirstName"/>
                            <Binding Path="LastName"/>
                        MultiBinding>
                    Setter.Value>
                Setter>
            Style>
        ComboBox.ItemContainerStyle>
  


How to deal with "CMD does not support UNC paths as current directories"

You need to use the "pushd" command instead of "cd" to change the current directory to a UNC path (e.g.: >pushd \\servername\sharename).

"the pushd command creates a temporary drive letter that points to the network resource, and then changes the current drive and folder to the new drive letter. Temporary drive letters are allocated starting from Z and then backward through the alphabet, using the first unused drive letter found."

Use "popd" when you're finished (e.g.: >popd) to cleanup the temporary mapped drive.

For more info see How To Use the PUSHD Command to Access a UNC Path at a Command Prompt in Windows 2000 (http://support.microsoft.com/kb/317379)

OR

Use powershell - which has complete support for unc paths.

How to iterate over the rows and cells in an Xceed WPF DataGrid

I found this handy code on the Xceed forums today. See http://xceed.com/CS/forums/permalink/26496/26518/ShowThread.aspx#26518

            foreach (object item in thisDataGrid1.Items)
            {
                Dispatcher.BeginInvoke(new Action<object>(DoRow), DispatcherPriority.ApplicationIdle, item);
            }

        private void DoRow(object item)
        {
            Xceed.Wpf.DataGrid.DataRow row = this.DataGrid1.GetContainerFromItem(item) as Xceed.Wpf.DataGrid.DataRow;
            if (row != null)
            {
                foreach (Xceed.Wpf.DataGrid.DataCell c in row.Cells)
                {
                    if (c != null)
                    {
                        //Do something to the cell
                    }
                }
            }
        }