5
\$\begingroup\$

I'm new at Caliburn Micro and the MVVM pattern.

I have 3 views (with its corresponding viewmodels):

  • AppView
  • ClientsView
  • EditClientView

AppView is my main page with a TabControl inside. The child views (WPF UserControls) are loaded in new tabs.

In ClientsView I have a grid with filtered clients. I select one, and when the Modify button is clicked I need to load a new tab with the editClientView and load its data. Here is my code:

public class EventAggregationProvider
{
    static EventAggregator _eventAggregator = null;
    public static EventAggregator EventAggregator
    {
        get
        {
            if (_eventAggregator == null)
                _eventAggregator = new EventAggregator();

            return _eventAggregator;
        }
    }
}

Function on ClientsViewModel:

public void ModificarCliente()
    {
        AppViewModel myParent = (AppViewModel)this.Parent;
        myParent.OpenTab(typeof(modClienteViewModel));
        EventAggregationProvider.EventAggregator.Publish(_selectedclient);
    }

MainViewModel OpenTab function:

public void OpenTab(Type TipoVista)
{
    bool bFound = false;
    if (TipoVista != null)
    {
        Screen myScreen = (Screen)Activator.CreateInstance(TipoVista as Type);
        myScreen.DisplayName = myScreen.ToString();
        foreach (Screen miItem in Items)
        {
            if (miItem.ToString() == myScreen.ToString())
            {
                bFound = true;
                ActivateItem(miItem);
            }
        }
        if (!bFound) ActivateItem(myScreen);
    }
}

EditClientViewModel:

class modClienteViewModel : Screen, IHandle<vw_ClientesFull>
{
    private OhmioService.OhmioServiceClient serviceClient =
        new OhmioService.OhmioServiceClient();        

    public Clientes Cliente { get; set; }

    public modClienteViewModel()
    {            
        EventAggregationProvider.EventAggregator.Subscribe(this);
        Cliente = new Clientes();            
    }

    public void Handle(vw_ClientesFull myClient)
    {            
        Cliente = serviceClient.Cliente_GetById(myClient.ID_Cliente);
        NotifyOfPropertyChange("Cliente");
    }
}

So what's your opinion on this? Especially about how I open the edit view (ClientsView becomes aware of the existence of MainWindowViewmodel and EditClientViewModel) from clients' viewmodel, and how I use eventaggregator to exchange the selected client between clientsViewModel and EditClientViewModel.

\$\endgroup\$
2
\$\begingroup\$

Naming

You should use PascalCase to name methods and types. You do this most of the time, but slip up with modClienteViewModel

Your parameters should be in camelCase. Again, you do this most of the time, but slip up with TipoVista in your OpenTab method.

Avoid Hungarian notation, with a modern IDE it's not necessary, and it just makes types harder to read.

bool bFound = false;

should be

var found = false;

The same probably goes for miItem which can just be item without any loss of meaning.

Var

Prefer to use var in a declaration when the right-hand side makes the type obvious.

e.g.

AppViewModel myParent = (AppViewModel)this.Parent;

is obvious because of the cast, so we write

var myParent = (AppViewModel)this.Parent;

The reasoning behind this is that if you wanted to change a type, you would have to do so in two places in one line. With var, it is only one change.

You should also use var when defining the loop variable in a foreach loop.

\$\endgroup\$
0
\$\begingroup\$

For the EventAggregator property in your EventAggregationProvider class you should use the ?? (null-coalescing) operator.

Definition:

The ?? operator is called the null-coalescing operator. It returns the left-hand operand if the operand is not null; otherwise it returns the right hand operand.

Your get will now look much cleaner:

public class EventAggregationProvider
{
    static EventAggregator _eventAggregator = null;

    public static EventAggregator EventAggregator
    {
        get
        {
            return _eventAggregator ?? new EventAggregator();
        }
    }
}

Casing:

From the Capitalization Conventions on MSDN:

  • Do use PascalCasing for all public member, type, and namespace names consisting of multiple words.
  • Do use camelCasing for parameter names.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.