Fork me on GitHub
Blog
The journal that this archive was targeting has been deleted. Please update your configuration.
Monday
Oct152012

Report a Message using a ViewModel

At times, you just want to display an informational message to the end user when something happens in you view. You can choose to display the message as part of your view or you can let the controller handle the displaying of message. To do so, you need to first create a ViewModel that represents a message, then send a behavior event from your view containing an instance of MessageViewModel, catch it from the controller and then report it to the end user (by displaying it as a modal message perhaps):

ViewModel that wraps the informational message:
public partial class MessageViewModel
{
    public string Identification { get; set; }
    public string Tittle { get; set; }
    public string Message { get; set; }
    public string Details { get; set; }
}
How you would send your message from your view:
this.SendBehaviorEvent(
    new BehaviorEvent<MessageViewModel>()
    {
        BehaviorReference = BehaviorReference.MessageDisplayBehavior,
        ViewModel = new MessageViewModel()
                        {
                            Message =
                                "Please accept terms and conditions.",
                            Tittle = "Warning"
                        }
    });
Catch your MessageViewModel from your controller and then display it:
public partial class Controller
{
    //Catching it before it gets executed
    protected override void OnBeforeBehaviorEvent<T>(
        IBehaviorEventSender<T> sender, 
        BehaviorEvent<T> behaviorEvent)
    {
        base.OnBeforeBehaviorEvent<T>(sender, behaviorEvent);

        if(behaviorEvent.BehaviorReference 
            == BehaviorReference.MessageDisplayBehavior)
        {
            var message = behaviorEvent.ViewModel as MessageViewModel;

            if (message != null)
            {
                this.RadToolTipMessage.Text = message.Message;
                this.RadToolTipMessage.Title = message.Tittle;
                this.RadToolTipMessage.Visible = true;
                this.RadToolTipMessage.Animation = 
                                        ToolTipAnimation.Fade;
                   
                this.RadToolTipMessage.Show();
            }
        }
    }
    
    //..I am using Telerik RadToolTip to display messages
    //..for more information how to use RadToolTip visit: 
    // http://www.telerik.com/products/aspnet-ajax/tooltip.aspx
    protected override void CreateChildControls()
    { 
        this.Controls.Add(this.RadToolTipMessage);

        base.CreateChildControls();
        base.EnsureChildControls();
    }
    protected override void OnInit(EventArgs e)
    {
        this.RadToolTipMessage = new RadToolTip()
        {
            ID = "RadToolTipMessage",
            Skin = "Metro",
            VisibleOnPageLoad = true,
            RelativeTo = 
                ToolTipRelativeDisplay.BrowserWindow,
            Visible = false,
            Position = ToolTipPosition.Center,
            HideEvent = ToolTipHideEvent.ManualClose,
            ShowDelay = 15000,
            AutoCloseDelay = 10000,
            HideDelay = 15000
        };

        base.OnInit(e);
    }
}
Friday
Oct122012

Catch and Report Behavior Exceptions

All Behaviors execution are isolated piece of methods that are wrapped with a Behavior class. The behaviors have no knowledge of how to report errors and they would just propagate the error (Exception) to the caller up the stack. Now, we want to catch errors whenever a behavior is executed and report it back to the user. To catch exceptions you would override OnBehaviorEvent from the controller and wrap it with a try..catch statement like this:
public partial class Controller
{
        // override OnBehaviorEvent from the Controller class
    protected override void OnBehaviorEvent<T>(
        IExecutableBehavior<T> executableBehavior, 
        BehaviorEvent<T> behaviorEvent)
    {
        try
        {
            base.OnBehaviorEvent<T>(
             executableBehavior, behaviorEvent);
        }
        catch(Exception ex)
        {
            // handle your exception here, in this case
            //..I am using Telerik RadToolTip to display messages
            //..for more information how to use RadToolTip visit: 
            //http://www.telerik.com/products/aspnet-ajax/tooltip.aspx
            this.RadToolTipMessage.Text = ex.Message;
            this.RadToolTipMessage.Title = "Error";
            this.RadToolTipMessage.Visible = true;
            this.RadToolTipMessage.Animation = ToolTipAnimation.Fade;
            this.RadToolTipMessage.Show();
        }
    }

    //..Initialize my RadToolTip
    protected override void OnInit(EventArgs e)
    {
        this.RadToolTipMessage = new RadToolTip()
        {
            ID = "RadToolTipMessage",
            Skin = "Metro",
            VisibleOnPageLoad = true,
            RelativeTo = ToolTipRelativeDisplay.BrowserWindow,
            Visible = false,
            Position = ToolTipPosition.Center,
            HideEvent = ToolTipHideEvent.ManualClose,
            ShowDelay = 15000,
            AutoCloseDelay = 10000,
            HideDelay = 15000
        };

        base.OnInit(e);
    }
    //adding my RadToolTip in my controller
    protected override void CreateChildControls()
    { 
        this.Controls.Add(this.RadToolTipMessage);

        base.CreateChildControls();
        base.EnsureChildControls();
    }
}
Thursday
Oct112012

Define Behavior Context Objects

Most times you want to define application context data that all views and all behaviors want to know about, for example current login name, user role, etc. You don’t want your views to fire a behavior event each time they need an application context data, or pass every application context data you need to every behavior execute method call. You would rather define it in the controller on InitBehaviorContext and all behaviors and views would be able to access it using their own property called “BehaviorContext” which is basically a key-value pair of application context objects.

public partial class Controller
{
    // ...
    // override InitBehaviorContext 
    // ..to define application context objects
    protected override void InitBehaviorContext()
    {
        base.InitBehaviorContext();

        var iden = WindowsIdentity.GetCurrent();
        (this as IBehaviorContext)["UserViewModel"] =
            new UserViewModel()
                {
                    LoginName = iden != null ? iden.Name : null,
                    Role = "regular-user"
                };
    }
}
// a behavior implementation
public partial class OpenStudentProfileBehavior
{
    public override void Execute(BehaviorEvent<StudentViewModel> args)
    {
        base.Execute(args);
        // getting a behavior context object
        var userViewModel = 
            this.BehaviorContext["UserViewModel"] as UserViewModel;

        if (userViewModel != null)
        {
            var loginName = userViewModel.LoginName;
            var role = userViewModel.Role;
        }
    }
}
//some random View called "MyView"
public partial class MyView 
{
    public override void OnAfterTransition<T>(
                                BehaviorEvent<T> behaviorEvent)
    {
        // Get a behavior context object after a behavior event 
        // is executed and the transition event 
        // is targeted to this view.

        base.OnAfterTransition<T>(behaviorEvent);
        var userViewModel = 
            this.BehaviorContext["UserViewModel"] as UserViewModel;

        if (userViewModel != null)
        {
            var loginName = userViewModel.LoginName;
            var role = userViewModel.Role;
        }
    }
    public void Bind(MyViewModel item)
    {
        // you can also get a behavior context object on bind
        var userViewModel = 
            this.BehaviorContext["UserViewModel"] as UserViewModel;
        if (userViewModel != null)
        {
            var loginName = userViewModel.LoginName;
            var role = userViewModel.Role;
        }
    }
}

 

Redefining Behavior Contexts

On occasions, you might want to redefine behavior context objects depending on what behavior is being executed. First you have to catch behavior you are looking for before it gets executed and then you would override the behavior context objects:

public partial class Controller
{
    protected override void OnBeforeBehaviorEvent<T>(
        IBehaviorEventSender<T> sender, 
        BehaviorEvent<T> behaviorEvent)
    {
        base.OnBeforeBehaviorEvent<T>(sender, behaviorEvent);
        
        // only override behavior context for a specific behavior 
        if(behaviorEvent.BehaviorReference 
                         == BehaviorReference.MyBehavior)
        {
            (this as IBehaviorContext)["UserViewModel"] =
            new UserViewModel()
            {
                LoginName = @"domain\somelogin",
                Role = "admin-role"
            };
        }
    }
}