ViewModelLocator for several entities in MVVM + Services

Feb 15, 2011 at 2:11 PM

After I saw John Papa’s presentation Kung Fu Silverlight I made similar project. Everything works fine till I added another View and ViewModel to process another entity, declaring of EmployeeViewModel employee doesn't work (execute OnEditEmployee, correct selectedEmployee (from ListBox) pass to EditEmployeeWindow, but in the EditEmployeeWindow shows that as set in GetEmployeesCallback.

This is only then i declare EmployeeViewModel employee in ViewModelLocator (red color), DepartmentViewModel department works correct.

The question is how can i declare correct EmployeeViewModel employee and others in ViewModelLocator?

public class EmployeeViewModel : ViewModel
    {

        public void LoadDepartments()
        {
            Departments.Clear();
            DepartmentDataService.GetEmployees(GetEmployeesCallback);
        }

        private void GetEmployeesCallback(IEnumerable<department> departments)
        {
            if (departments != null)
            {
                foreach (var department in departments)
                {
                    Employees.Add(department);
                }
                if (Employees.Count > 0)
                {
                    SelectedEmployee = Employees[0];
                }
              }
        }

        private void OnEditEmployee()
        {
            Messenger.Default.Send(new LaunchEditEmployeeMessage() { employee = SelectedEmployee });
        }

}

public partial class employeeView : Page
    {
        public employeeView()
        {
            InitializeComponent();
            RegisterMessages();
        }

        private void RegisterMessages()
        {
            Messenger.Default.Register<LaunchEditEmployeeMessage>(this, OnLaunchEditEmployee);
            Messenger.Default.Register<SaveEmployeeDialogMessage>(this, OnEditEmployeeDialogMessageReceived);
        }

        private void OnLaunchEditEmployee(LaunchEditEmployeeMessage msg)
        {
            var editEmployee = new EditEmployeeWindow();
            editEmployee.Show();
        }

        private void OnEditEmployeeDialogMessageReceived(SaveEmployeeDialogMessage msg)
        {
            MessageBox.Show(msg.Content, msg.Caption, msg.Button);
        }

}

<navigation:Page    xmlns:local="clr-namespace:departmentTechManager"
    x:Class="departmentTechManager.Views.employeeView"
           ...
    xmlns:mvvmlightcmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4"
    DataContext="{Binding employee, Source={StaticResource Locator}}">   

<grid><sdk:Page.Resources>
        <DataTemplate x:Key="employeeItemTemplate">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding name}"/>
            </StackPanel>
        </DataTemplate>
    </sdk:Page.Resources>

...

<ListBox ItemsSource="{Binding Employees}"   x:Name="employeeListBox"  ItemTemplate="{StaticResource employeeItemTemplate}"
    SelectedItem="{Binding SelectedEmployee, Mode=TwoWay}"  /><grid/>

 

 

public class ViewModelLocator
    {
        private readonly ServiceProviderBase _sp;

        public ViewModelLocator()
        {
            _sp = ServiceProviderBase.Instance;

            // 1 VM for all places that use it. Just an option
            department = new DepartmentViewModel(_sp.PageConductor, _sp.DepartmentDataService); //this works
        }

        public DepartmentViewModel department { get; set; } //this works

        //this doesn't work
        public EmployeeViewModel employee
        {
            get { return new EmployeeViewModel(_sp.PageConductor, _sp.EmployeeDataService); }
        }

    }

Feb 15, 2011 at 2:25 PM

one more thing, there is Assets\ObjectResourceDictionary.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local1="clr-namespace:departmentTechManager.ViewModels"
    xmlns:local="clr-namespace:departmentTechManager"
    xmlns:Common="clr-namespace:departmentTechManager.Papa.Common" >
    <Common:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
    <local:ViewModelLocator x:Key="Locator" />
</ResourceDictionary>

Feb 16, 2011 at 2:08 PM

Sorry, the question was almost stupid. I’ve solved the problem, just read properly MVVM light toolkit manual, although I’ve had to remove readonly property from ServiceProviderBase and use Quick Replace instead of MvvmLight.Snippets (use VS2010 Express).

here is the code:

public class ViewModelLocator

    {

        private static  ServiceProviderBase _sp;//readonly

 

        /// <summary>

        /// Cleans up all the resources.

        /// </summary>

        public static void Cleanup()

        {

            Cleardepartment();

            Clearemployee();

        }

 

        /// <summary>

        /// Initializes a new instance of the ViewModelLocator class.

        /// </summary>

        public ViewModelLocator()

        {

 

            _sp = ServiceProviderBase.Instance;

 

            //CreateMain();

 

            Createdepartment();

            Createemployee();

 

        }

 

 

#region DepartmentViewModel

        private static DepartmentViewModel _department;

 

        /// <summary>

        /// Gets the department property.

        /// </summary>

        public static DepartmentViewModel departmentStatic

        {

            get

            {

                if (_department == null)

                {

                    Createdepartment();

                }

 

                return _department;

            }

        }

 

        /// <summary>

        /// Gets the department property.

        /// </summary>

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",

            "CA1822:MarkMembersAsStatic",

            Justification = "This non-static member is needed for data binding purposes.")]

        public DepartmentViewModel department

        {

            get

            {

                return departmentStatic;

            }

        }

 

        /// <summary>

        /// Provides a deterministic way to delete the department property.

        /// </summary>

        public static void Cleardepartment()

        {

            //do it later

            //_department.Cleanup();

            _department = null;

        }

 

        /// <summary>

        /// Provides a deterministic way to create the department property.

        /// </summary>

        public static void Createdepartment()

        {

            if (_department == null)

            {

                _department = new DepartmentViewModel(_sp.PageConductor, _sp.DepartmentDataService);

            }

        }

        #endregion