Click here to Skip to main content
15,887,444 members
Articles / Desktop Programming / WPF

If Behaviors Complete MVVM, Then?

Rate me:
Please Sign up or sign in to vote.
4.88/5 (4 votes)
29 Dec 2013CPOL2 min read 5.8K   4  
Sometimes we need to have an independent View-ViewModel part which divides a part of the work to an independent module. Why do we do this?

Introduction

In the WPF world, we always like to separate View and ViewModel parts and we like to use MVVM pattern to accomplish that. But sometimes, we also need to have an independent View-ViewModel part which divides a part of the work to an independent module. Why do we do this?

If possible, we should classify our events defined in our .xaml. Because some of the events work only for UI changing, some others serve for business logic layer. In some cases, we could band these business events with a ViewModel, but sometimes we don’t want to make our ViewModel confused that one ViewModel contains more than two business logics. Especially when ViewModel does just updating of UI’s data source.

In the case above, we could use Behaviors to separate an independent logic of business layer mission with UI events. We don’t care anymore about the relationship between View and ViewModel, because I do my job and my business is almost nothing relative with others. (But here, please make sure about the requirement with your team so that you’ll really not have a conflict.)

Image 1

Background

In one of my projects, I defined my ViewModel to be the part which does only updating of UI data source, nothing else. My UI part provides several click-event functions which use selected data row to do some other operations. These operations will not influence directly UI’s data source. Other events and click-events in the UI part serve only for change of UI, they don’t touch business layer.

Using the Code

Blocks of code: Behaviors was injected into a BarManager. BarManager contains a TreeListControl. TreeListControl contains a ContextMenu which referenced BarManager’s barButtonItem. If one of the barButtonItems in the ContextMenu is clicked, ContextMenu_ItemClick event will invoke directly Business layer functions to react user’s click. And this behavior is used for only its corresponding business layer, not for anything else.

C#
public class ContextMenuBehaviours : Behavior<BarManager>
{
    private TreeListControl _treeListControl;
    private BarManager _barManager;

    protected override void OnAttached()
    {
        AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);
    }

    void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        if (_barManager == null)
        {
            _barManager = sender as BarManager;
            _treeListControl = _barManager.Child as TreeListControl;
            var barButtons = _barManager.Items.Where(p => p is BarButtonItem);
            foreach (var button in barButtons)
            {
                (button as BarButtonItem).ItemClick += 
                  new ItemClickEventHandler(ContextMenu_ItemClick);
            }
        }
    }

    void ContextMenu_ItemClick(object sender, ItemClickEventArgs e)
    {
        try
        {
            if ((sender as BarButtonItem).Name != null && _treeListControl != null)
            {
                string clientName = (_treeListControl.SelectedItem != null) ? 
                  ((_treeListControl.SelectedItem as UIOrder).CLIENTID ?? "All") : "All";
                switch ((sender as BarButtonItem).Name)
                {
                    case "PretradeBarButtonItem":
                        ContextMenuEvents.RunPretradeBarButtonItem("", null);
                        break;
                    case "PosttradeBarButtonItem":
                        break;
                    ...
                        break;
                    case "CreateExecutionBarButtonItem":
                        ContextMenuEvents.RunCreateExecutionBarButtonItem(_treeListControl);
                        break;
                    default:
                        break;
                }
            }
        }
        catch (Exception exp)
        {
            EXOE.ExoeManager.Core.Log.ExoeToolLog.Fatal(exp);
        }
    }

    protected override void OnChanged()
    {
        base.OnChanged();
    }

    protected override void OnDetaching()
    {
        _treeListControl = null;
        _barManager = null;
        GC.Collect();
        base.OnDetaching();
    }
}
//

Here’s a piece of code of how behaviors is used:

Image 2

Points of Interest

Why do I like to separate another logic part like what I wrote above? Because there are several advantages:

  • More chance for parallel teamwork (development and test), save more time or make the program more robust.
  • Easy to find problems when errors occur.

It’s also a disadvantage that we should be more careful about teamwork communication in this case.

History

First version, please give your suggestions and comments.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
France France
A foolish 18 years old boy
Just got an Microsoft C# Specialist Certification. Objectif of this year : MCSD

Comments and Discussions

 
-- There are no messages in this forum --