Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version
Go to top

Building an Extensible Application with MEF, WPF, and MVVM

, 15 Nov 2009
An article for anyone interested in how to build an extensible application using WPF and the Model-View-ViewModel pattern.
SoapBox.Demo.Setup.zip
SoapBox.Demo.Setup
setup.exe
SoapBox.Demo.Setup.msi
SoapBoxCoreWithDemo.zip
SoapBoxCoreWithDemo
AvalonDock
AvalonDock
AvalonDock.snk
doc
AvalonDock.shfb
Help
LastBuild.log
DrWPF
GreyableImage
Properties
Settings.settings
Resources
DocumentHS.png
images
Aero
AeroDockBottom.png
AeroDockBottomHover.png
AeroDockLeft.png
AeroDockLeftHover.png
AeroDockPane.png
AeroDockPaneBottom.png
AeroDockPaneInto.png
AeroDockPaneLeft.png
AeroDockPaneRight.png
AeroDockPaneTop.png
AeroDockRight.png
AeroDockRightHover.png
AeroDockTop.png
AeroDockTopHover.png
Classic
PinAutoHide.png
PinAutoHideSelected.png
PinClose.png
PinCloseSelected.png
PinMenu.png
PinMenuSelected.png
DockBottom.PNG
DockLeft.PNG
DockPane.PNG
DockRight.PNG
DockTop.PNG
HTabGroup.png
Locked.png
PinAutoHide.png
PinClose.png
PinDocMenu.png
PinMenu.png
Thumbs.db
VTabGroup.png
themes
bin
NLog
src
NLog.snk
NLog
Conditions
Config
DotNet
Filters
Internal
FileAppenders
NetworkSenders
Win32
LayoutRenderers
Layouts
Mono
NLog.vs2003.csdproj
Targets
Compound
Wrappers
Unix
Web
Win32
LayoutRenderers
Targets
Physics2D
AdvanceMath
Design
Geometry2D
IO
Properties
Physics2DDotNet
Collections
DataTypes
Detectors
Ignorers
Joints
Physics2DDotNet.csproj.user
PhysicsLogics
Properties
Shapes
Solvers
References
System.ComponentModel.Composition.dll
Release
SoapBox
CodeSnippets
PropArgs.snippet
PropName.snippet
SoapBox.Core
SoapBox.Core.Arena
Arena
ArenaBodies
Physics
Utility
Properties
SoapBox.Core.Arena.csproj.user
SoapBox.Core.Contracts
App
Startup
Conditions
Gui
Controls
Layout
MenuItem
Options
StatusBar
StatusBarButton
StatusBarLabel
StatusBarRadioButton
StatusBarSeparator
StatusBarToggleButton
ToolBar
ToolBarItem
ToolBarButton
ToolBarLabel
ToolBarRadioButton
ToolBarSeparator
ToolBarToggleButton
ViewModel
Properties
Services
ExtensionService
LoggingService
Utilities
SoapBox.Core.Host
Properties
app.manifest
Settings.settings
SoapBox.Core.Layout
Layout
Properties
SoapBox.Core.Logging
Properties
Services
LoggingService
SoapBox.Core.Options
Options
Properties
Resources
cog.png
Workbench
MainMenu
SoapBox.Core.Workbench
Properties
Settings.settings
Resources
SoapBox.Core.Workbench.csproj.user
Workbench
MainMenu
SoapBox.Demo
SoapBox.Demo.HighScores
Layout
Pads
PinBall
Properties
Settings.settings
Resources
Workbench
MainMenu
SoapBox.Demo.PinBall
App
StartupCommands
star.png
Arena
ArenaBodies
Pin
PinBall
PinBallBonus
PinBallBottomBumper
PinBallBottomRamp
PinBallFlipper
PinBallFlipperMount
PinBallKicker
PinBallLauncher
PinBallLevel
PinBallPartition
PinBallReturnRamp
PinBallRoundedTop
PinBallSensor
PinBallStop
PinBallTableEdge
PinBallTarget
Options
Pads
Properties
Settings.settings
Resources
Sounds
beat1.wav
beat2.wav
bonus_fast.wav
brooomm.wav
doodoodoodoo.wav
driiinng2.wav
flip.wav
rattata_single.wav
tack.wav
tick.wav
time.wav
SoapBox.Demo.PinBall.csproj.user
Sound
Workbench
MainMenu
StatusBar
SoapBox.Demo.Setup
Debug
SoapBox.Demo.Setup.vdproj
#region "SoapBox.Core License"
/// <header module="SoapBox.Core"> 
/// Copyright (C) 2009 SoapBox Automation Inc., All Rights Reserved.
/// Contact: SoapBox Automation Licencing (license@soapboxautomation.com)
/// 
/// This file is part of SoapBox Core.
/// 
/// Commercial Usage
/// Licensees holding valid SoapBox Automation Commercial licenses may use  
/// this file in accordance with the SoapBox Automation Commercial License
/// Agreement provided with the Software or, alternatively, in accordance 
/// with the terms contained in a written agreement between you and
/// SoapBox Automation Inc.
/// 
/// GNU Lesser General Public License Usage
/// SoapBox Core is free software: you can redistribute it and/or modify 
/// it under the terms of the GNU Lesser General Public License
/// as published by the Free Software Foundation, either version 3 of the
/// License, or (at your option) any later version.
/// 
/// SoapBox Core is distributed in the hope that it will be useful, 
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
/// GNU Lesser General Public License for more details.
/// 
/// You should have received a copy of the GNU Lesser General Public License 
/// along with SoapBox Core. If not, see <http://www.gnu.org/licenses/>.
/// </header>
#endregion
        
using System;
using System.Collections.Generic;
using System.Windows.Input;
using System.ComponentModel;

namespace SoapBox.Core
{
    public abstract class AbstractCommandControl : AbstractControl, ICommandControl
    {

        #region " ICommand Implementation "

        public event EventHandler CanExecuteChanged = delegate { };

        public bool CanExecute(object parameter)
        {
            return EnableCondition.Condition;
        }

        public void Execute(object parameter)
        {
            Run();
        }

        #endregion

        /// <summary>
        /// This method is called when the command is executed.
        /// Override this in the derived class to actually do something.
        /// </summary>
        protected virtual void Run() { }

        #region " EnableCondition "
        /// <summary>
        /// Defaults to AlwaysTrueCondition.
        /// Set this to any ISoapBoxCondition object, and it will control
        /// the CanExecute property from the ICommand interface, and 
        /// will raise the CanExecuteChanged event when appropriate.
        /// </summary>
        public ICondition EnableCondition
        {
            get
            {
                if (m_EnableCondition == null)
                {
                    // Lazy initialize this property.
                    // We could do this in the constructor, but 
                    // I like having it all contained in one
                    // section of code.
                    EnableCondition = new AlwaysTrueCondition();
                }
                return m_EnableCondition;
            }
            protected set
            {
                if (value == null)
                {
                    throw new ArgumentNullException(m_EnableConditionName);
                }
                if (m_EnableCondition != value)
                {
                    if (m_EnableCondition != null)
                    {
                        //remove the old event handler
                        m_EnableCondition.ConditionChanged -= OnEnableConditionChanged;
                    }
                    m_EnableCondition = value;
                    //add the new event handler
                    m_EnableCondition.ConditionChanged += OnEnableConditionChanged;
                    CanExecuteChanged(this, new EventArgs());

                    NotifyPropertyChanged(m_EnableConditionArgs);
                }
            }
        }
        private ICondition m_EnableCondition = null;
        static readonly PropertyChangedEventArgs m_EnableConditionArgs =
            NotifyPropertyChangedHelper.CreateArgs<AbstractCommandControl>(o => o.EnableCondition);
        static readonly string m_EnableConditionName =
            NotifyPropertyChangedHelper.GetPropertyName<AbstractCommandControl>(o => o.EnableCondition);
        private void OnEnableConditionChanged(object sender, EventArgs e)
        {
            CanExecuteChanged(sender, e);
        }
        #endregion


    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

Share

About the Author

Scott Whitlock
Engineer
Canada Canada
By day I'm a Professional Engineer, doing .NET, VB6, SQL Server, and Automation (Ladder Logic, etc.) programming.
 
On weekends I write and maintain an open source extensible application framework called SoapBox Core.
 
In the evenings I provide front line technical support for moms4mom.com and I help out with administrative tasks (like formatting stuff). I also pitch in as a moderator from time to time.
 
You can follow me on twitter.

You may also be interested in...

| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 15 Nov 2009
Article Copyright 2009 by Scott Whitlock
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid