Caliburn Micro #02 : BindableCollection & Events

In the previous part of this series, we looked into some of the basics of using Caliburn Micro. In this part, we will continue with few more examples, how to invoke a method on an event.

But before we do that, let’s expand our application a bit. Currently the application has two Text controls , wired up to a property (FirstName) in the View Model. Let’s expand it further and have 2 more properties, LastName and FullName.

Our expanded ViewModel Looks like following now.


private string _FirstName = "Jia Anu";

public string FirstName
 {
 get { return _FirstName; }
 set
 {
 _FirstName = value;
 NotifyOfPropertyChange(nameof(FirstName));
 NotifyOfPropertyChange(nameof(FullName));
 }
 }

private string _LastName;

public string LastName
 {
 get { return _LastName; }
 set {
 _LastName = value;
 NotifyOfPropertyChange(nameof(LastName));
 NotifyOfPropertyChange(nameof(FullName));
 }
 }

We will add additional controls to our View, and add the necessary binding.

        <!--Row 1 Starts here -->
        <Label Grid.Column="0" Grid.Row="0">Full Name</Label>
        <TextBlock Text="{Binding Path=FullName, Mode=OneWay}" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2"></TextBlock>
        <!--Row 1 Ends here -->

        <!--Row 2 Starts here -->
        <Label Grid.Column="0" Grid.Row="1">First Name</Label>
        <TextBox x:Name="FirstName" Grid.Row="1" Grid.Column="1"></TextBox>
        <!--Row 2 Ends here -->

        <!--Row 3 Starts here -->
        <Label Grid.Column="0" Grid.Row="2">Last Name</Label>
        <TextBox x:Name="LastName" Grid.Row="2" Grid.Column="1"></TextBox>
        <!--Row 3 Ends here -->

Bindable Collections

Let’s expand it futher, let’s introduce a model now. We will add a model in our Model Folder.

public class DeparmentModel
{
public string DepartmentName { get; set; }
public string Supervisor { get; set; }

}

And introduce two new properties for our View Model.

private BindableCollection _DepartmentCollection = new BindableCollection();

public BindableCollection DepartmentCollection
{
get { return _DepartmentCollection; }
set
{
_DepartmentCollection = value;

}
}

private DeparmentModel _SelectedDepartment;

public DeparmentModel SelectedDepartment
{
get { return _SelectedDepartment; }
set
{
_SelectedDepartment = value;
NotifyOfPropertyChange(nameof(SelectedDepartment));
}
}

We will delve more into BindableCollection later, but for now, let’s think of it as a means for binding to a combo box. Since we are not using any Db for this example, lets hard code some values in the constructor.

public ShellViewModel()
{
DepartmentCollection.Add(new DeparmentModel() { DepartmentName = "Finance", Supervisor = "John Tommothy" });
DepartmentCollection.Add(new DeparmentModel() { DepartmentName = "Development", Supervisor = "Alex Brown" });
DepartmentCollection.Add(new DeparmentModel() { DepartmentName = "Human Resource", Supervisor = "Dennis Burton" });
}

We will add a Combo box and another Text Area in our XAML to accodomate the changes. The XAML looks like following now.

        <!--Row 4 Starts here -->
        <Label Grid.Column="0" Grid.Row="3">Department</Label>
        <ComboBox Grid.Column="1" Grid.Row="3" ItemsSource="{Binding DepartmentCollection}" DisplayMemberPath="DepartmentName"
                 SelectedItem="{Binding SelectedDepartment,Mode=OneWayToSource}" ></ComboBox>
                <!--Row 4 Ends here -->

        <!--Row 5 Starts here -->
        <Label Grid.Column="0" Grid.Row="4">Supervisor</Label>
        <TextBlock Grid.Column="1" Grid.Row="4" x:Name="SelectedDepartment_Supervisor"></TextBlock>
        <!--Row 5 Ends here -->

Run our application and you can now see the combo box in action. Everytime you change the Department, the corresponding Supervisor is displayed the TextArea.

Events and EventGuards

Now then, lets head to adding a button to clear the selected values. We will first introduce a method.

public void ClearTextMethod(string firstName,string lastName)
{
FirstName = string.Empty;
LastName = string.Empty;
}

We are passing two parameters, however we are not quite using it. However, the sigificance of the parameters come into light when we add our second method, CanClearTextMethod

public bool CanClearTextMethod(string firstName, string lastName)
{
return !string.IsNullOrEmpty(firstName);
}

Notice the naming patterns used for the methods and parameters. The ‘Can’ Method is named in such a way that it prepends ‘Can’ to the ClearTextMethod. This aids Caliburn Micro to recognize this method needs to be evaluated to enable CanClearTextMethod.

Also the parameters. They are named as similiar as the FirstName and LastName Properties. These are the properties which dictate whether to enable the method or not, which is being passed as paramers. Ensure the naming is correct and Caliburn Micro does the magic for you.

Lets add the necessary XAML for adding a button and wiring it up with the method.

        <Button Grid.Column="0" Grid.Row="5" x:Name="ClearTextMethod">Clear</Button>

The entire code sample for this examples can be found here. 

Complete List of Tutorials on Caliburn.Micro can be found here

Caliburn Micro #01 : Introduction

It has been long since i blogged, having caught up with the Product Release and Year End Vaccations. As the calender turns, it would be a good time to learn something new.

If you are building an WPF application and is looking out for MVVM Frameworks, you would be surprised with the amount of choices you are bestowed with. Despite Prism standing out as aruguably the most complete package available, there are times when you would like to try out a different framework. That brings us to Caliburn Micro, a light weight MVVM Framework, which might not be as powerful as Prism, but still does its work in a simple and easy way.

Bonus :  Caliburn.Micro Starter Kit Extensions for WPF is now available at Visual Studio Marketplace

Okay, that’s for an Intro, lets get our hands dirty and create a customary ‘Hello World’ app using Caliburn Micro. Let’s kick start our Visual Studio , create a new WPF Application and do the obvious step, add ‘Caliburn Micro’ Nuget package.

CM Demo 01.JPG

Once you have the necessary dependencies in, we will start with creating our ‘Hello World’ application. Normal WPF application would have ideally looked for the “StartupUri” Tag under your app.xaml to kick start your first page. The Caliburn.Micro works differently. So lets first go ahead and remove the StartUri tag and replace it with bit of XAML to ensure it takes advantages of features of Caliburn.Micro.

Our App.Xaml would now look like following.

<Application x:Class="App001.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:App001"
             >
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <local:Bootstrapper x:Key="Bootstrapper"></local:Bootstrapper>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

As you can see we have replaced the StartupUri and added a Resource Dictionary called Bootstrapper. At this point, Bootstrapper doesn’t exist, so we will go ahead and create it. Bootstrapper will act as the entry point for our WPF application and would point to the Screen that needs to be loaded first.


public class Bootstrapper : BootstrapperBase
 {
 #region Constructor
 public Bootstrapper()
 {
 Initialize();
 }
 #endregion

 protected override void OnStartup(object sender, StartupEventArgs e)
 {
 DisplayRootViewFor();
 }
}

As seen in the code above, the Bootstrapper class is derieved from BootstrapperBase class from the Caliburn.Micro library. We have done two things here.
a) Called the Initialize method in the default constructor.
b) Override ‘OnStartUp’ method and called a single method, DisplayRootViewFor, pointing to the Base View Model which we want to load first. In this particular example, we have called it ShellViewModel.

As in the earlier case, we do not have the ShellViewModel class defined at the moment, which obviously becomes our next step. Prior to which, we will create 3 folders, each representing the three components of MVVM in the project – Models, Views, ViewModels. Remember naming the folders exactly the same, with names denoting plurals, so that we can take advantage of the Caliburn Magic.

We will now create the ShellViewModel Class under the ViewModels Folder.


public class ShellViewModel:Screen
{
}

Let’s keep it simple for the moment, san any properties and derieve it from Screen Class ( we will delve into other derivative options later). We will add the View for the ViewModel, again keeping it devoid of complicated controls for the sake of example.

        <TextBlock Text="Jia"></TextBlock>
        <TextBox>Jia</TextBox>

As seen the in code above, we have called it ShellView and have placed it under the Views Folder. The naming is of foremost importance here as the Caliburn Framework relies heavily on the naming conventions to wireup the View and View Model. Unlike, Prism you don’t need to set the ‘Autowireviewmodel’ property, this is being automatically done by the Caliburn framework as long as you follow the naming convensions.

For sake of simplicity being the first example, we have hard coded the values for TextBlock and TextBox, we will replace it with binding as we move on with the example.

That’s it, you are all set to run the basic ‘Hello World’.

Okay, let’s now add couple of Properties and bind them to our controls. Let’s go ahead and create the properties in ViewModel.


private string _FirstName = "Jia Anu";

public string FirstName
{
get { return _FirstName; }
set
{
_FirstName = value;
NotifyOfPropertyChange(nameof(FirstName));
}
}

Now let’s head towards the View and wireup the FirstName property. Modified XAML looks as below.

           <TextBlock Text="{Binding Path=FirstName, Mode=OneWay}" ></TextBlock>
        <TextBox x:Name="FirstName" ></TextBox>

Now you can run the application and see the magic of MVVM model in action via Caliburn Micro. In the next post, we will delve more into the CM features. The code for this project can be found here

Evil Code #004 : Conditional Attribute

Continuing with our series of subtle changes that make differences, let’s look into Conditional Attributes over Directives.

static void Main(string[] args)
{
Method01();
Method02();

Queue queue = new Queue();
queue.Enqueue("One");
queue.Enqueue("Two");
queue.Enqueue("Three");

Method03(queue.Dequeue());
Console.WriteLine(queue.Count);
Console.WriteLine("All Done");
Console.ReadLine();
}

// Approach One
private static void Method01()
{
#if DEBUG
Console.WriteLine("Hello Method01");
#endif
}
[Conditional("DEBUG")]
private static void Method02()
{
Console.WriteLine("Hello Method02");
}

[Conditional("DEBUG")]
private static void Method03(string Value)
{
Console.WriteLine(Value);
}

What would be the output of above code under
a) Debug Mode
b) Release Mode

The Debug Mode should be easy and as expected

Hello Method01
Hello Method02
One
2
All Done

What about release mode ?
3
All Done

You might have a tendency to say “2”, considering you might expect the dequeue statement to be executed. However, that is not the case. The dequeue is not called either because the result is not used as the method is not called.This leads to unexpected errors .
This is one the reasons why it is recommended not to decorate a method that accepts parameter with conditional Attributes.

Evil Code #003 : Casting

Welcome to first post on ‘Back to basics’. Yeah, as you guessed right, this series attempt to check minor differences in our understanding of basic concepts.

Predict the output of following.


public class FirstType
{

}
public class SecondType
{
private FirstType _mType;

public static implicit operator FirstType(SecondType t)
{
return t._mType;
}
}

static void Main(string[] args)
{
object objectInstance = new SecondType();

FirstType attempt1 = objectInstance as FirstType;
if (attempt1 != null)
{
Console.WriteLine("'As' Conversion Succeeded");
}
else
{
Console.WriteLine("'As' Conversion Failed");
}

try
{
FirstType attempt2 = (FirstType)objectInstance;
Console.WriteLine("Cast Succeeded");
}
catch (Exception)
{
Console.WriteLine("Cast Failed");
}

}

Ideally, One would expect the first attempt to fail, but would feel the second would succeed considering we have implemented implicit conversion. But unfortunately, that’s not the case. The output would be

‘As’ Conversion Failed.
Cast Failed.

The reason for this is that, the compiler generates code based on the compile time type of the objectInstance, which in this case is ‘object’. It then checks if there is any conversion declared to convert object to FirstType, which doesn’t exist. The compiler doesn’t check the type of the objectInstance during runtime, which results in the above output.

The reason for this is that, the compiler generates code based on the compile time type of the objectInstance, which in this case is ‘object’. It then checks if there is any conversion declared to convert object to FirstType, which doesn’t exist. The compiler doesn’t check the type of the objectInstance during runtime, which results in the above output.

Updated

The behavior is even more tricky when we change the type of¬†objectInstance from ‘object’ to SecondType. We would expect it to work smoothly now, however, you end up with a compiler exception this time .

“Cannot convert type ‘Cast.SecondType’ to ‘Cast.FirstType’ via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion”

This is what makes ‘as’ operators great as it provides early detection of errors. The ‘as’ operator, notices that there is a implicit conversion declared between FirstType and SecondType. However, it also recognizes that two types aren’t related by inheritance. This is the reason ‘as’ statements throws a compile-time error at this stage.

 

Design Patterns : Adapter Pattern

There is already a large amount of literature on the Internet which discusses Adapter Pattern. However, the purpose of article is to showcase the implementations of the Adapter Pattern, rather than discussing the application of the pattern. In this post, adapter class is implemented using

1. Inheritance
2. Dependency Injection
3. Generics

Consider your old legacy code, which has a single method, GetEmployeeList.

public interface IHRSoftware
    {
        List<string> GetEmployeeNameList();
    }
    public class HRSoftware : IHRSoftware
    {
        public List<string> GetEmployeeNameList()
        {
            return new List<string>() { "Jia", "Anu", "Sreena" };
        }
    }

Client, consumes the class as follows.

            IHRSoftware hrsoft = new HRSoftware();
            foreach (var item in hrsoft.GetEmployeeNameList())
            {
                Console.WriteLine(item);
            }

Now, it so happened that the Client has gone through an overhaul and is now looking to use a new contract (interface), namely INewAgeSoftware, which exposes a property EmployeeList, replacing the GetEmployeeNameList Method. The interface declaration is as shown below.

    public interface INewAgeHRSoftware
    {
        List<string> EmployeeList { get;  }
    }

You however, would like to use your old existing code, without actually going ahead and making the changes in your legacy code. This is where adapter pattern come in handy. Following are different implementations of Adapter Class

1. Using Inheritance.

    public class AdapterWithInheritence : HRSoftware, INewAgeHRSoftware
    {

        public List<string> EmployeeList
        {
            get
            {
                return this.GetEmployeeNameList();
            }
        }
    }

2. Using Dependency Injection

    public class AdapterWithDI : INewAgeHRSoftware
    {
        private IHRSoftware _HRInstance;
        public AdapterWithDI(IHRSoftware HRSoftInstance)
        {
            _HRInstance = HRSoftInstance;
        }
        public List<string> EmployeeList
        {
            get
            {
                return _HRInstance.GetEmployeeNameList();
            }
        }
    }

3. And Finally, using Generics

    public class AdapterWithGenerics<T> : INewAgeHRSoftware where T : HRSoftware
    {
        private T _HRInstance;
        public AdapterWithGenerics(T Instance)
        {
            _HRInstance = Instance;
        }

        public List<string> EmployeeList
        {
            get
            {
                return _HRInstance.GetEmployeeNameList();
            }
        }
    }

Your new Client class would now look as follows

 Console.WriteLine("Fetching from NewAgeHRSoftware - Adapter via Inheritence");
            INewAgeHRSoftware newhrsoftInheritence = new AdapterWithInheritence();
            foreach (var item in newhrsoftInheritence.EmployeeList)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("Fetching from NewAgeHRSoftware - Adapter via DI");
            INewAgeHRSoftware newhrsoftDI = new AdapterWithDI(new HRSoftware());
            foreach (var item in newhrsoftInheritence.EmployeeList)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("Fetching from NewAgeHRSoftware - Adapter via Generics");
            INewAgeHRSoftware newhrsoftGenerics= new AdapterWithGenerics<HRSoftware>(new HRSoftware());
            foreach (var item in newhrsoftGenerics.EmployeeList)
            {
                Console.WriteLine(item);
            }

Serialize Deserialize NameValueCollection

Don’t ask me why one cannot Serialize/Deserialize a NameValueCollection, but the workaround for the same is based on conversion to dictionary. I ended up writing extension methods to NameValueCollection for serializing and deserializing the collection.

public static string JSONSerialize(this NameValueCollection _nvc)
{
return JsonConvert.SerializeObject(_nvc.AllKeys.ToDictionary(k => k, k =>_nvc.GetValues(k)));
}
public static void JSONDeserialize(this NameValueCollection _nvc,string _serializedString)
{
var deserializedobject = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(_serializedString);
foreach (var strCol in deserializedobject.Values)
foreach (var str in strCol)
_nvc.Add(deserializedobject.FirstOrDefault(x => x.Value.Contains(str)).Key, str);
}

An Introduction into Dicom using Fellow Oak

DICOM (Digital Imaging and Communication in Medicine) is probably the most common standard used for storage and exchange of Medical Images. This article provides a basic introduction on reading a Dicom File using C#.

The basic unit of a Dicom file is called an Element. Dicom Elements consists of 4 components

1. Tag
2. Value Representation
3. Value Length
4. Value Field

Tag
Tag uniquely identifies each element in the file. It consists of 2 short numbers representing the group and element.

Value Representation
Value Representation is an optional field, which defines the datatype of the element. For example,
UI – Unique Identifier
CS – Custom String
OS – Other Byte
US – Unsigned Short

Value Length
This even sized field would contain the length of the field. This field would always be even sized.

Value Field
Value Field as expected, would contain the actual value.

Reading a Dicom Element is pretty easy in C#. For this example, am using Fellow Oak Dicom Library for .Net.

Following lines of code would read the patient name out of a Dicom File using the Fellow Oak Library

 Dicom. DicomFile obj = Dicom.DicomFile .Open(FilePath);
var PatientName = obj.Dataset.Get( DicomTag.PatientName, null );

The Fellow Oak Library provides a simple interface to read all Dicom Elements.

More on Dicom in next post.