Articles in categories

Now on Amazon

Converter: Image path converter

An image converter to convert an empty string (image path) to an "Image not found" image or an image placeholder.

I use it when there is no image specified for my object's ImagePath property. When the ImagePath property is Null or Empty, then it shows an imageplaceholder, retrieved from a staticresource.

using System;
using System.Windows;
using System.Windows.Data;

namespace XpressNetTrainController
{
	public class ImageStringConverter:  IValueConverter
	{
		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			var imagePath = (string)value;
			if (!String.IsNullOrEmpty(imagePath))
				return imagePath;

			return Application.Current.Resources["NoImageController"];
		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			return null;
		}
	}
}

And in the App.xaml:

<BitmapImage x:Key="NoImageController">Images/LocController/no_image.png</BitmapImage >
<local:ImageStringConverter x:Key="ImageStringConverter" />

 

Start console application and read output in WPF

Method to start an Console Application from WPF and read it's output text in a TextBox. Preferable a multiline TextBox with auto-scrolling.

public void StartProcess()
{
	try
	{
		using (var selProcess = new Process())
		{
			selProcess.StartInfo.FileName = Directory.GetCurrentDirectory() + @"\ConsoleTest.exe";
			selProcess.StartInfo.CreateNoWindow = true;
			selProcess.StartInfo.UseShellExecute = false;
			selProcess.StartInfo.RedirectStandardOutput = true;

			// Event Handler
			selProcess.OutputDataReceived += SortOutputHandler;

			// Start the process
			selProcess.Start();

			// Read output
			selProcess.BeginOutputReadLine();
		}
	}
	catch (Exception ex)
	{
		MessageBox.Show(Application.Current.MainWindow, ex.Message, "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
	}
}

private void SortOutputHandler(object sender, DataReceivedEventArgs e)
{
	Trace.WriteLine(e.Data);
	Dispatcher.BeginInvoke(new Action(() =>
	{
		// LogText is a databount string dp property to a TextBox
		LogText += e.Data + Environment.NewLine;
	}));
}

 

DesignerProperties.GetIsInDesignMode

Disable a part of code when in DesignerMode

      if (!DesignerProperties.GetIsInDesignMode(this)) // check if not in DesignerMode
      {
        // do something
      }

 

An AttachedProperty to make a WPF (multiline) TextBox automatically scroll to the end. (autoscrolling)

An AttachedProperty to make a WPF (multiline) TextBox automatically scroll to the end -> autoscrolling-textbox

Found this solution on StackOverflow.

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

namespace Stieven.Utils
{
  /// <summary>
  /// Attached Property to make a (multiline) TextBox always scroll to the end
  /// http://stackoverflow.com/questions/10097417/how-do-i-create-an-autoscrolling-textbox
  /// </summary>
  public static class TextBoxUtilities
  {

    public static readonly DependencyProperty AlwaysScrollToEndProperty = 
      DependencyProperty.RegisterAttached("AlwaysScrollToEnd",typeof(bool),typeof(TextBoxUtilities),new PropertyMetadata(false, AlwaysScrollToEndChanged));

    private static void AlwaysScrollToEndChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
      var tb = sender as TextBox;
      if (tb != null)
      {
        bool alwaysScrollToEnd = (e.NewValue != null) && (bool)e.NewValue;
        if (alwaysScrollToEnd)
        {
          tb.ScrollToEnd();
          tb.TextChanged += TextChanged;
        }
        else
        {
          tb.TextChanged -= TextChanged;
        }
      }
      else
      {
        throw new InvalidOperationException("The attached AlwaysScrollToEnd property can only be applied to TextBox instances.");
      }
    }

    public static bool GetAlwaysScrollToEnd(TextBox textBox)
    {
      if (textBox == null)
      {
        throw new ArgumentNullException("textBox");
      }

      return (bool)textBox.GetValue(AlwaysScrollToEndProperty);
    }

    public static void SetAlwaysScrollToEnd(TextBox textBox, bool alwaysScrollToEnd)
    {
      if (textBox == null)
      {
        throw new ArgumentNullException("textBox");
      }

      textBox.SetValue(AlwaysScrollToEndProperty, alwaysScrollToEnd);
    }

    private static void TextChanged(object sender, TextChangedEventArgs e)
    {
      ((TextBox)sender).ScrollToEnd();
    }
  }
}

Usage:

<TextBox Grid.Row="1"
	        Name="textBoxLog"
	        Margin="5"
		TextWrapping="Wrap"
		AcceptsReturn="True"
		VerticalScrollBarVisibility="Auto"
		Utils:TextBoxUtilities.AlwaysScrollToEnd="True"
		Text="{Binding LogText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

Also available as a download:

 

Event to Command in MVVM

Here's how to bind a control's event to an MVVM command. You can use the 'System.Windows.Interactivity' dll that is a part of the Expression Blend SDK.

A simple example:

<ComboBox Name="comboBox1"
		   SelectedItem="{Binding SelectedItem,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
		   ItemsSource="{Binding ItemsList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
	<i:Interaction.Triggers>
		<i:EventTrigger EventName="SelectionChanged">
			<i:InvokeCommandAction Command="{Binding MyVMCommand}" />
		</i:EventTrigger>
	</i:Interaction.Triggers>
</ComboBox>

 It's also possible to pass a parameter to the command. In this case I pass the ComboBox's SelectedItem to the command:

<ComboBox Name="comboBox1"
	  SelectedItem="{Binding MySelectedItem,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
	  ItemsSource="{Binding ItemsList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
	<i:Interaction.Triggers>
		<i:EventTrigger EventName="SelectionChanged">
			<i:InvokeCommandAction Command="{Binding MyVMCommand}" 
							      CommandParameter="{Binding SelectedItem, ElementName=comboBox1}"/>
		</i:EventTrigger>
	</i:Interaction.Triggers>
</ComboBox> 

After you've added it to your project, you just need to include the 'System.Windows.Interactivity' dll into your XAML namespaces.

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

That assembly can be found in the  Expression Blend SDK which is a free download (it also gets installed with Expression Blend), or through the internet.

After you installed the Expression Blend SDK you can find it here:

For WPF:
C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\.NETFramework\v4.0\Libraries

For Silverlight:
C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\Silverlight\v4.0\Libraries

However you can just download it here and include it into your project references.