Thursday, October 20, 2011

Improving .Net Framework

I was thinking a lot of times about a way of forcing types to have some common constructor. Of course this can be achieved by abstract classes - but the derieved classes can hide it. So the way I was hoping it to be is through the interfaces - to be able to specify a signature of a contructor, the implementing types should have.
Am so happy that Microsoft has Connect :) So my idea is already there - go and vote for it here

Let's see what will they decide.

Tuesday, October 18, 2011

Remote Assistance within MVVM based applications

Even we - IT professionals, require a lot of web assistance during our daily life. One of the cases I was facing several days ago was a problem during the payment for an item in Amazon. As usual, the user calls to the support, describes the situation, gets a lot of clarifying questions, and being asked for about three times to repeat, just to ensure that he hasn't missed something.
This is a problem - a big problem both for the customer, who is facing a problem and the support guy, who is just unable to vividly see the situation happening on the customer machine. And the thing the Support man can dreams of in those cases - is a remote connection.
Of course in 99.9% of cases such a luxary will be impossible, and the reason is only the firewalls, the client - who doesn't even know what the remote desktop connection is, ... .
But all we are living in an eWorld - and most of the things we do are related to the internet - onlin shopping, emails, some new account registration, blogging, ... . So I thought that there must be a better way of support, and there is. Of course, it won't fit the requirements of all the users, but it can cover most of the cases. And in this blogpost I will try to bring the idea I do have which can change the way of support.
So let's imagine that the application, which we're adding the support for is designed using MVVM pattern. What does this mean ? This means, that whole the logic of the application is being handled by the ViewModel class instance (in simple case there can be only one class in ViewModel layer). And based on any change on that class the UI is being changed accordingly. So what if someone, who is using the same application, will be able to simulate the same changes in the same order on a ViewModel layer obects on his machine, as the user on his machine ? This will mean, that the UI on both machines will have the same state after every single change, which, in its place, means that both users will have the same view. All this is true, until there is some User-Specific logic in the appilcation, which can change the way the Application behaves depending the logged in user. Let's for now leave this open point for later discussion (in this post of course), and assume that there is a solution for this as well, and both users can log in by the same user.
So, if we will come up with some service, which transmitts any change from one application instance to another we will have a simple screen sharing between those two users. To acomplish this we need a centralized way of transfering the changes in one ViewModel to another.
Remember that a ViewModel class in Silverlight, implements the INotifyPropertyChanged interface, which in its place defines the PropertyChanged event. And any change which can cause the UI to update, being tranfered to the UI throught firing this event. So what we can do is by simply registering to the ViewModel class instance's PropertyChanged event, and pass any change of any property to a service (I will not go into the code, but will just concentrate on the logic here. Please write your comments to the post, and I will try to respond shortly). Transfering to the service all this data is no enough, because there must be some unique token, which by the data should be identified. And this token should be shared with the other party (The support guy in our case), so he will be able to attach his UI to that token as a listener on the service, so any change coming to the service should be transfered to the Support Application Instance (SAI later: the application instance which the support guy has onpened on his machine for remote assistance). This will now bring any UI change to the SAI.
So in this case we got something which is very like a screen sharing application - but the actual sharing. Of course this is a lot already, and the Support guy will know now how the user goes from one point from another in the UI, but let's not stop on this, and continue developing the idea.
Based on all this we can achieve the same from the other side, and bring any change that is being done on the SAI, to the Customer Application. This will mean already, that the application is being remotely controlled.
And that's all. Of course I haven't spent time describing minor things like the user must first allow the Support guy to remotely see his changes, and how he is going to get that unique token, ... and a lot more, but I tryed to explain whole the working solution I do see, which I hope, can bring a big change to the online application support.

All the best to all of you, and enjoy :)

Tuesday, October 4, 2011

Dialogs in MVVM (Silverlight)

Several days ago I was facing a problem, when was trying to open/show a dialog from in my MVVM application.
The actual problem is that I want that dialog also to be bound to a ViewModel instance - controlling it.
There are many approaches to handle this. I will present one of them - which I am satisfied with.
So, let's start. What I want is to have a DialogViewModel instance in my main ViewModel object, which is the DataContext of the current page, and which from from I'm going to open the dialog.
When thinking of MVVM itself you think that is much be something like setting a property and a dialog must show up - THAT IS CORRECT ! And that is what I'm going to achieve.
So just to give a small example of code, how the structure should be:

public class PageViewModel
{
    private DialogViewModel dialogVM = new DialogViewModel();

    public DialogViewModel DialogVM
    {
        get
        {
            return this.dialogVM;
        }
    }
}

public class DialogViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool show = false;

    private void NotifyPropertyChange(string argPropertyName)
    {
        PropertyChangedEventHandler tmpEH = this.PropertyChanged;
        if(tmpEH != null)
            tmpEH(this, new PropertyChangeEventArgs(argPropertyName));
    }

    // Here comes a lot of logic like dialog commands, ... which I will not include in this article

    public bool Show
    {
        get
        {
            return this.show;
        }
        set
        {
            if(value != this.show)
            {
                this.show = value;
                this.NotifyPropertyChange("Show");
            }
        }
    }
}

This is quiete enough for the ViewModel layer. So this is really what I've described enough. You will now ask - how should this boolean change (althought it supposed to be such thing) affect the dialog to appear - keep reading.
The simple approach (which won't work with ChildWindow derieved dialogs) is to add a dialog definition into the XAML and bind its Visibility property to the DialogVM.Show property, using a BoolToVisibilityConverter (am sure you'll be able to write something like this yourself). But when you'll try to do this, the dialog will behabe strange - it will really be not what you wanted - and you'll notice a lot of issues with it. Maybe in further versions of Silverlight this way of showing dialogs also will be possible - but not yet.
So, the second approach, I'll keep with, is to create a helper class, derieved from Control class. This will be the actual bridge between the DialogVM and the dialog we're going to show.
Here what the helper control will look like:

public class DialogHelper : Control
{
    //...
}

But an empty class is not going to be any helpfull for us. And here the core of the solution is: we're going to add a DependencyProperty to this control - to enable it to be bound to anything, bind it with the DialogVM.Show property and finally handle the change of that dependency property.

public class DialogHelper : Control
{
    private static readonly DependencyProperty ShowProperty = DependencyProperty.Register("Show", typeof(bool), typeof(DialogHelper), new PropertyMetadata(false, new PropertyChangedCallback(OnShowChanged)));

    private static void OnShowChanged(DependencyObject argSender, DependencyPropertyChangedEventArgs argEA)
    {
        ConfirmationDialogHelper tmpSender = argSender as ConfirmationDialogHelper;
        if(tmpSender.Show)
        {
            DialogToShow tmpDialog = new DialogToShow();
            //The following line makes sure that the dialog also will work based on MVVM
            tmpDialog.DataContext = (this.DataContext as PageViewModel).DialogVM;
            tmpDialog.Show();
        }
    }
}

So, finally, here is the way you should handle it in MVVM - ENJOY !!!

P.S.
Please sorry for any code typos, cause I was typing it right into the blog editor - with no IntelliSence support.