Thursday, July 31, 2014

MVVm views without C# code behind file

The MVVm is a great technique for separating the concerns. If we take ASP.Net MVC we can see it is built for using model view controller model. So by default wont allow us to write code behind for the views (We can write inside the cshtml though). But WPF as the technology was not built to use WPF to there is no in-built way to avoid the code behind of views. 

If the development team is so technology focused, it doesn't matter as they won't break the rules of MVVm even if there is code behind file. But since companies are offshoring to get cheap labor, enforcing quality is little tricky. As always cheap things comes with less quality. Most of the time people's priority is to get things done in quick way ie by writing everything in code behind instead of going through viewmodel. 

The challenge here is how to bring quality with these less skilled labor? One of the way to enforce viewmodel  usage is to delete the code behind of views which is nothing but the user controls.

If we just remove the usercontrol.xaml.cs, it will fail as the Initialize method is missing. So how to overcome is?

Add the Initialize method in the view itself. Yes we can write C# code in XAML. So the view user control will look as follows.

<UserControl x:Class="Joymons.MVVmDemo.Views.MainView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <x:Code>
        <![CDATA[ public MainView() { InitializeComponent(); }]]>
    </x:Code>
            <TabControl ItemsSource="{Binding ChildVMs}" SelectedIndex="0">
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Header}" />
                    </DataTemplate>
                </TabControl.ItemTemplate>
            </TabControl>
</UserControl>

I too started using VS 2013. That is why a black background in the code :)

Thursday, July 3, 2014

Binding Viewmodel property to tabitem header in MVVm pattern

Its been a while since I started a WPF project from scratch. I was mainly into the architectural side of application rather than UI side. Today I got an opportunity to start one app. It is supposed to be simple WPF application where the screens are arranged in hierarchical tabs.

The application is supposed to be a temporary application which will be used to test an algorithm developed by the business before its getting integrated into the actual application. So thought of not following the MVVm pattern as its supposed to be developed from our offshore in less amount of time. But one discussion with my lead architect changed my decision. If we are doing something we should do it right. We don't know whether the client will get rid of the application if it feels too good for them. Finally decided to go with MVVm.

The initial decision I had to take about the MVVm infrastructure. Earlier when I used to start the project I take my own RelayCommand,ViewmodelBase classes. That was the beginning time of WPF. But this time I decided to use a good library on the assumption that the MVVm framework must be matured by now. It ends up in using MVVM Light. Its a nice library which we can get from nuget.

Then started thinking about the UI structure where the tabs needs to be shown in hierarchical way. Its nothing but there will be one parent level tab control and in every tab page there will be one more tab control. I created the view models and bound to the view. Each high level view model have ChildVMs collection. In the MainPage.xaml UI I was able to bound to the ChildVMs property and they showed up as each and every viewmodel was associated with data template.

    <Application.Resources>
        <DataTemplate DataType="{x:Type vms:ChildViewmodel_1}">
            <vws:ChildViewUserControl_1/>
        </DataTemplate>
    </Application.Resources>

But I faced one problem. I could see that the tab headers are also showing the same control which is inside the tab page. Ideally I need to edit the tab header template and bind to the header property in the viewmodel. But I could see one more way which is just a data template for the tab item.

        <TabControl ItemsSource="{Binding ChildVMs}">
            <TabControl.ItemTemplate>
               
                <DataTemplate>
                    
                    <TextBlock Text="{Binding Header}" />
                </DataTemplate>
            </TabControl.ItemTemplate>
        </TabControl>

Happy coding