Replaceing the default difference/merge tool in Visual Studio with WinMerge is fairly easy, but I keep forgetting, so I figured I'd do a quick write-up.

Subversion (SVN)

After installing WinMerge, in Visual Studio, go to 

Tools -> Options -> Source Control and depending on your Source Control selection (in the case here Subversion) look for a 'Tools' menu (with Subversion its under Subversion User Tools):

If you are using Subversion/TortoiseSVN you can simply select WinMerge from the 'External Diff Tool' and 'External Merge Tool' combo boxes:

 

As always feel to ask or comment.


.RemoveWhere extension

Published 11/1/2017 by Christian

Hi All,

 

Just a quick extension this time.

This one returns an IEnumerable<T> where all source items that fulfills a given conditions has been removed.

I've called it RemoveWhere.

 

Anyway - here you are:

public static IEnumerable<TSource> RemoveWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> removeSelector)
{
	List<TSource> result = new List<TSource>();
	foreach (var s in source)
	{
		if (!removeSelector(s))
		{
			result.Add(s);
		}
	}

	return result; 
}

Can be used as:

WarehousePrinters = info.Printers.RemoveWhere(p => string.IsNullOrEmpty(p.PrinterID)).ToList();

As always feel to ask or comment.


Hi,

In this post I will gather my Visual Studio code snippets

First a snippet for creating a property and backing field, and raising OnPropertyChanged when the backing field has changed.

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>proppropertychanged</Title>
			<Shortcut>proppropertychanged</Shortcut>
			<Description>Code snippet for property and backing field, and raising OnPropertyChanged when the backing field has changed</Description>
			<Author>Christian Klint Baltz Nielsen</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>type</ID>
					<ToolTip>Property type</ToolTip>
					<Default>int</Default>
				</Literal>
				<Literal>
					<ID>property</ID>
					<ToolTip>Property name</ToolTip>
					<Default>MyProperty</Default>
				</Literal>
				<Literal>
					<ID>field</ID>
					<ToolTip>The variable backing this property</ToolTip>
					<Default>myVar</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><![CDATA[private $type$ $field$;
	public $type$ $property$
	{
		get { return $field$;}
		set 
		{ 
			if($field$ != value)
			{
				$field$ = value;
				OnPropertyChanged(() => $property$);
			}
		}
	}
	$end$]]>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

It will create the following code:

private string _imageLabel;
public string ImageLabel
{
	get { return _imageLabel; }
	set
	{
		if (_imageLabel != value)
		{
			_imageLabel = value;
			OnPropertyChanged(() => ImageLabel);
		}
	}
}

Another one for creating a 'lazy loading property' or 'self initializing property'

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>proplazyload</Title>
            <Shortcut>proplazyload</Shortcut>
            <Description>Code snippet for property and backing field, with initializing backing field if its null</Description>
            <Author>Christian Klint Baltz Nielsen</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>type</ID>
                    <ToolTip>Property type</ToolTip>
                    <Default>int</Default>
                </Literal>
                <Literal>
                    <ID>property</ID>
                    <ToolTip>Property name</ToolTip>
                    <Default>MyProperty</Default>
                </Literal>
                <Literal>
                    <ID>field</ID>
                    <ToolTip>The variable backing this property</ToolTip>
                    <Default>myVar</Default>
                </Literal>
            </Declarations>
            <Code Language="csharp"><![CDATA[private $type$ $field$;
    public $type$ $property$
    {
        get 
		{ 
			if($field$ == null)
			{
				$field$ = new $type$();
			}
			return $field$;
		}
    }
    $end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

It will create the following code:

private string _imageLabel;
public string ImageLabel
{
    get
    {
        if (_imageLabel == null)
        {
            _imageLabel = new string();
        }
        return _imageLabel;
    }
}

 

Very often I call my return variable 'result', so a snippet that 'return result' would be nice for me. Here it is:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>if</Title>
			<Shortcut>rr</Shortcut>
			<Description>Code snippet for returning result</Description>
			<Author>Christian Klint Baltz Nielsen</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
				<SnippetType>SurroundsWith</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Code Language="csharp"><![CDATA[return result; $end$]]>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

and the output:

return result;

As always feel to ask or comment.

 


In Visual Studio (at least 2017) you can add a WPF Window to a WinForms project by slighty modifying the .csproj file.

Just add

<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

To the end of the first

<PropertyGroup>

 tag.

It ends up looking something like this:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <ProjectType>Local</ProjectType>
	.
	.
	.
    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
  </PropertyGroup>
.
.
.

As always, feel free to comment, or ask.


A Simple WPF DataGrid using MVVM

Published 9/15/2017 by Christian in Code
Tags: , , ,

Her follows a simple WPF DataGrid.

In the Visual Studio Design view it look like this:

The DefaultButtonStyle and DefaultDataGrid style can be found elsewhere in this blog.

Ill include the XAML for the entire Window.

<Window x:Class="Ellab.Main.Sessions.Chamber.WPFUnitSelection.UnitSelectionView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Ellab.Main.Sessions.Chamber.WPFUnitSelection"
        mc:Ignorable="d"
        Title="{Binding Title}" x:Name="MainWindow" Height="300" Width="750">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Ellab.WPF;component/View/Styles/ButtonStyle.xaml"/>
                <ResourceDictionary Source="pack://application:,,,/Ellab.WPF;component/View/Styles/DataGridStyle.xaml"/>
                <ResourceDictionary Source="MvvmResources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid Background="{Binding Background, FallbackValue=Red}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <DataGrid Grid.Row="0" ItemsSource="{Binding Rows, FallbackValue=AllTheSmartRows}" Style="{StaticResource DefaultDataGrid}" HeadersVisibility="Column" AutoGenerateColumns="False" VerticalAlignment="Top" SelectionMode="Single" SelectionUnit="FullRow" SelectedItem="{Binding SelectedItem}">
            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <EventSetter Event="MouseLeftButtonDown" Handler="DataGrid_MouseLeftButtonDown"/>
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="#FF009CDD" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.RowStyle>
            <DataGrid.Columns>
                <DataGridTextColumn Header="{Binding UnitIDHeader, FallbackValue=ID}" Binding="{Binding UnitID, FallbackValue=ID}" MinWidth="75" Width="Auto" IsReadOnly="True"/>
                <DataGridTextColumn Header="{Binding TypeHeader, FallbackValue=Type}" Binding="{Binding Type, FallbackValue=Type}" MinWidth="75" Width="Auto" IsReadOnly="True"/>
                <DataGridTextColumn Header="{Binding UnitTypeHeader, FallbackValue=Unit Type}" Binding="{Binding UnitType, FallbackValue=Unit}" MinWidth="75" Width="Auto" IsReadOnly="True"/>
                <DataGridTextColumn Header="{Binding NameHeader, FallbackValue=Name}" Binding="{Binding Name, FallbackValue=Name}" MinWidth="125" Width="Auto" IsReadOnly="True"/>
                <DataGridTextColumn Header="{Binding DescriptionHeader, FallbackValue=Description}" Binding="{Binding Description, FallbackValue=Description}" MinWidth="25" Width="*" IsReadOnly="True"/>
            </DataGrid.Columns>
        </DataGrid>
        <Grid Grid.Row="1" Background="White" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="40">
            <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Margin="5" Command="{Binding HelpClickedCommand}" Width="30" Style="{StaticResource DefaultButtonStyle}" Background="#FF123F74">
                    <Image Source="../../Resources/Help.png"/>
                </Button>
                <Button Margin="5" Content="{Binding ViewButtonContent, FallbackValue=#View}" Command="{Binding ViewClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding ViewVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding AddNewButtonContent, FallbackValue=#Add New}" Command="{Binding AddNewClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding AddNewVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding EditButtonContent, FallbackValue=#Edit}" Command="{Binding EditClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding EditVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding RemoveButtonContent, FallbackValue=#Remove}" Command="{Binding RemoveClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding RemoveVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding ImportButtonContent, FallbackValue=#Import}" Command="{Binding ImportClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding ImportVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding ExportButtonContent, FallbackValue=#Export}" Command="{Binding ExportClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding ExportVisible}" MinWidth="75"/>
                <Button Margin="5" Content="{Binding OKButtonContent, FallbackValue=#OK}" Command="{Binding OKClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding OKVisible}" IsDefault="True" MinWidth="75"/>
                <Button Margin="5" Content="{Binding CloseButtonContent, FallbackValue=#Close}" Command="{Binding CloseClickedCommand}" Style="{StaticResource DefaultButtonStyle}" Visibility="{Binding CloseVisible}" IsCancel="True" MinWidth="75"/>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

Allthough using the MVVM design patten, I've opted to handel  event in the codebehind, as in my opinion this is View releated. Here is the event handler

namespace Ellab.Main.Sessions.Chamber.WPFUnitSelection
{
    /// <summary>
    /// Interaction logic for UnitSelectionView.xaml
    /// </summary>
    public partial class UnitSelectionView : Window
    {
        private UnitSelectionView()
        {
            InitializeComponent();
        }

        public UnitSelectionView(UnitSelectionViewModel mainContext)
            : this()
        {
            DataContext = mainContext;
        }
        private void DataGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DataGridRow clickedRos = sender as DataGridRow;
            clickedRos.IsSelected = true;
        }
    }
}

As always, feel free to comment, or ask.


The System.Linq.Distinct extension returns a list (or more to the point, an IEnumerable<>) of ... surprise ... distinct items in a list.

This is all well and good for simple data types (e.g. integers). But what if you have more complex data types, and you want to get a distinct list based on a specific property.

Well - Distinct extension enumerates the Object.Equals method on all items in the list, and returns a new list list based on the result. An object is only equal to another object if they have the same hash code. So running List<T>.Distinct() would only exclude items from List<T> where T are the same object, and not items with the same information.

Say you have a Student type:

public class Student
{
    public long ID { get; set; }
    public string Name { get; set; }

    public Student(long id, string name)
    {
        ID = id;
        Name = name;
    }
}

And a Class:

public class Class
{
    private List<Student> _students { get; } = new List<Student>() { new Student(1, "John Doe"), new Student(1, "John Doe"), new Student(2, "Jane Doe") };
}

Running 

IEnumerable<Student> distinctStudent = _students.Distinct();

would give you 3 items, as both "John Doe" have unique HashCode - they are not the same object.

There are two ways of getting about this.

Either override Object.Equals(object obj) and Object.GetHashCode() on the Student type:

public class Student
{
    public long ID { get; set; }
    public string Name { get; set; }

    public Student(long id, string name)
    {
        ID = id;
        Name = name;
    }

    public override bool Equals(object obj)
    {
        var student = obj as Student;
        return this.ID.Equals(student?.ID);
    }
    public override int GetHashCode()
    {
        return ID.GetHashCode();
    }
    public override string ToString()
    {
        return Name;
    }
}

This executes fairly fast, but you would only be able to get unique items based on their ID.

If you want a more customisable way, you could write an extension:

public static class Extensions
{
    public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
    {
        HashSet<TKey> seenKeys = new HashSet<TKey>();
        foreach (TSource item in source)
        {
            if (seenKeys.Add(keySelector(item)))
            {
                yield return item;
            }
        }
    }
}

and user it like this:

public class Class
{
    private List<Student> _students { get; } = new List<Student>() { new Student(1, "John Doe"), new Student(1, "John Doe"), new Student(2, "Jane Doe") };

    public IEnumerable<Student> GetDistinct()
    {
        return _students.Distinct();
    }

    public IEnumerable<Student> GetDistinctBy()
    {
        return _students.DistinctBy(s => s.ID);
    }

    public IEnumerable<Student> GetDistinctByMore()
    {
        return _students.DistinctBy(s => new { s.ID, s.Name });
    }
}

As always, feel free to comment, or ask.


You can delete a TFS branch from the Visual Studio Developer Command Prompt, using the 'tf destroy' command. The syntax is as follows:

C:\tf delete $/TeamProject/Branch

This is also valid for folder or files.

C:\tf delete $/MyTeamProject/Folder
C:\tf delete $/MyTeamProject/Folder/File

Of course remember to put any Branch/Folder/Files with spaces in, inside quotes:

C:\tf delete $/MyTeamProject/"Branch No 1" 

As always, feel free to comment, or ask.

Getting an ancestor property value can be done by binding to its element name. Here's an example

<Grid Width="{Binding Width}" Margin="{Binding Margin}">
	<Border BorderBrush=" #FF17447E" BorderThickness="5">
		<StackPanel Name="MainStackPanel" Orientation="Vertical">
			<ScrollViewer Height="{Binding ElementName=MainStackPanel, Path=ActualHeight}">
				<ItemsControl ItemsSource="{Binding Rows, FallbackValue=Rows}" Background="Transparent">
					<ItemsControl.ItemsPanel>
						<ItemsPanelTemplate>
							<StackPanel Orientation="Vertical"/>
						</ItemsPanelTemplate>
					</ItemsControl.ItemsPanel>
					<ItemsControl.ItemTemplate>
						<DataTemplate>
							<ContentPresenter Content="{Binding}" Height="30"/>
						</DataTemplate>
					</ItemsControl.ItemTemplate>
				</ItemsControl>
			</ScrollViewer>
		</StackPanel>
	</Border>
</Grid>

As always, feel free to comment, or ask


Exciting new stuff for C# 7

Published 4/11/2016 by Christian

Sounds like there are som exciting new stuff in waiting for C# programmers.

Personally, I've never like tuples, but it looks like they are going to make sense, since you can now give the var's names.

Anyway - a link to the 2016 build presentation: https://channel9.msdn.com/events/build/2016/b889

And here is another from the Visual Studio 2017 Launch: https://channel9.msdn.com/Events/Connect/2016/105?ocid=player

More from the VS2017 Launch: https://channel9.msdn.com/Events/Visual-Studio/Visual-Studio-2017-Launch/140

 

 

 


WPF Controls has no ‘InvokeRequired’/’Invoke’ like WinForms, so making accessing a WPF Window/Control threadsafe can be accomplished by using the System.Windows.Threading.Dispatcher. Here are some examples. First a property: 

 

public int Progress
{
	get
	{
		if (!Dispatcher.CheckAccess())
		{
			Func<int> f = delegate () { return Progress; };
			return Dispatcher.Invoke(f);
		}

		...
	}
	set
	{
		if (!Dispatcher.CheckAccess())
		{
			Action<int> a = delegate (int progress) { Progress = progress; };
			Dispatcher.Invoke(a);
			return;
		}

		...
	}
}

 

  A void method

 

 

public void SetProgress(object obj, int progress)
{
	if (!Dispatcher.CheckAccess())
	{
		Action<object, int> a = new Action<object, int>(SetProgress);
		Dispatcher.Invoke(a, DispatcherPriority.Normal, obj, progress);
		return;
	}

	...
}

 

And lastly a method with a return value

 

 

public bool AllProcessesDone()
{
	if (!Dispatcher.CheckAccess())
	{
		Func<bool> f = new Func<bool>(AllProcessesDone);
		return Dispatcher.Invoke(f, DispatcherPriority.Normal);
	}

	...
}

 

As always, feel free to comment, or ask.