Menu

[2011.01.06] Drag and Drop in WPF using MVVMLight [IV/IV]

2011-01-06 - C#, MVVM, WPF
[2011.01.06] Drag and Drop in WPF using MVVMLight [IV/IV]

downloadCode02
This is a multipart series outlining several topics is WPF.

  1. Part 1: MVVM via the MVVMLight framework
  2. Part 2: Drag and Drop
  3. Part 3: The Adorner
  4. Part 4: DataTemplateSelector, StyleSelector, Unit Testing

In this final part, I will outline some other features that supplement the application and provides a better user experience. This was done primarily as a demonstration of the features, namely DataTemplateSelector and StyleSelector.

The Data Template Selector

You use a DataTemplateSelector to display data from the same collection differently, based on some criteria in the data. For example, the Contact type has a property, Crew, which is a Faction enumeration. Please take a look at the Contact class in the code to download to see the definitions. In this case, I will use different DataTemplates based on which Faction each member belongs to. The different templates are defined in the ResourceDictionary1.xaml file.
You need to inherit from from the DataTemplateSelector base class and override the SelectTemplate() method. This is all illustrated in Listing 1.

using System.Windows;
using System.Windows.Controls;
using DragDropUsingMvvmLight01.Model;

namespace DragDropUsingMvvmLight01
{
    /// <summary>
    /// Extended class used to change the data template of each ListBoxItem based on some custom requirement. 
    /// </summary>
    public class FactionDataTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            var frameworkElement = container as FrameworkElement;
            
            if (frameworkElement !=null && item is Contact )
            {
                Contact contact = item as Contact;  // Contact is the type hosted in each ListBoxItem

                if (contact.Crew == Faction.Strawhat)
                    return (DataTemplate)frameworkElement.TryFindResource("SourceListBoxItemTemplate");
                return (DataTemplate)frameworkElement.TryFindResource("SourceListBoxDataTemplate02");
            }
            return null;
        }
    }
}

The Style Selector

The reason and strategy follows the same pattern as in the template selector case, so I will just add the code to Listing 2 and let you take it from there.

using System.Windows;
using System.Windows.Controls;
using DragDropUsingMvvmLight01.Model;

namespace DragDropUsingMvvmLight01
{
    /// <summary>
    /// Extended class used to change the style of each ListBoxItem based on some custom requirement. 
    /// </summary>
    public class ListBoxStyleSelectors : StyleSelector
    {
        public override Style SelectStyle(object item, DependencyObject container)
        {
            FrameworkElement frameworkElement = container as FrameworkElement;

            if (frameworkElement != null && item is Contact)
            {
                Contact contact = item as Contact; // Contact is the type hosted in each ListBoxItem

                if (contact.Crew == Faction.Strawhat)
                    return (Style)frameworkElement.TryFindResource("SourceListBoxItemStyle1");
                return (Style)frameworkElement.TryFindResource("SourceListBoxItemStyle2");
            }
            return null; 
        }   
    }
}
Listing 2: Implementation of a StyleSelector

Unit Testing

I am brand spanking new at this. I only did tests for the Contact model as I was not sure how to test the view models. I used NUnit as my testing framework. Thus far, I did not have to use any stubs or mocks. See Listing 3 for the code.

using System.Collections.ObjectModel;
using NUnit.Framework;
using DragDropUsingMvvmLight01.Model;

namespace DragDropUsingMvvmLight01.Tests
{
    [TestFixture]
    public class ContactTests
    {
        private Contact _contact = null;
        private ObservableCollection<Contact> _contacts;

        #region Setup
        [SetUp]
        public void Setup()
        {
            _contact = new Contact();
            _contacts = _contact.GetContacts();
        }
        #endregion

        [Test]
        public void GetContacts_ReturnValueIsNotNull_ReturnsTrue()
        {
            Assert.That(_contacts, Is.Not.Null);
        }

        [Test]
        public void GetContacts_IsTypeofContact_ReturnsTrue()
        {
            Assert.That(_contact, Is.InstanceOf<Contact>());   
        }

        [Test]
        public void GetContacts_HasAtLeastOneItemInCollection_ReturnsTrue()
        {
            Assert.That(_contacts.Count, Is.GreaterThanOrEqualTo(1));
        }

        [Test]
        public void GetContacts_ObjectIsInGoodState_ReturnsTrue()
        {
            var contact = _contacts[0];
            var firstNamePropertyIsNotNullOrEmpty = contact.Name;
            var lastNamePropertyIsNotNullOrEmpty = contact.Alias;
            var phonePropertyIsAValidNumber = contact.Race;
            var profileImageUrlPropertyIsNotNullOrEmpty = contact.ProfileImageUrl;
            Assert.That(string.IsNullOrEmpty(firstNamePropertyIsNotNullOrEmpty), Is.False);
            Assert.That(string.IsNullOrEmpty(lastNamePropertyIsNotNullOrEmpty), Is.False);
            Assert.That(phonePropertyIsAValidNumber, Is.Not.NaN);
            Assert.That(string.IsNullOrEmpty(profileImageUrlPropertyIsNotNullOrEmpty), Is.False);
            
        }

        #region Teardown
        [TearDown]
        public void Teardown()
        {
            _contact = null;
        }
        #endregion      
    }
}
Listing 3: Unit tests for the Contact model

One thought on “[2011.01.06] Drag and Drop in WPF using MVVMLight [IV/IV]

Robertas Balandis

Download link does’t work

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>