BrianKE
BrianKE

Reputation: 4185

Dependency Injection not working

I have been learning MVVM / WPF and have gone through the tutorial here.

I have created a working application using this methodology but now, on a new project, I cannot get the Dependency Injection to work.

When I run this project I get an empty MainWindow without the CompanyView injected. I have double and tripled checked everything between the project that works and this one that doesn't and cannot find the reason for CompanyView not being injected. I have also tried cleaning the solution and restarting VS to no avail. Hopefully someone can see what I am missing.

I have the following file:

App.xaml.cs (using base.OnStartup() instead of StartupUri in App.xaml)

namespace SidekickAdmin
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            MainWindow window = new MainWindow();
            var viewModel = new MainWindowViewModel();
            window.DataContext = viewModel;
            window.Show();
        }

    }
}

MainWindowViewModel.cs

namespace SidekickAdmin.ViewModel
{
    class MainWindowViewModel : ViewModelBase
    {
        public MainWindowViewModel()
        {
            CompanyViewModel companyViewModel = new CompanyViewModel(_repository);
            this.ViewModels.Add(companyViewModel);

        }

        ObservableCollection<ViewModelBase> _viewModels;
        ObservableCollection<ViewModelBase> ViewModels
        {
            get
            {
                if (_viewModels == null)
                {
                    _viewModels = new ObservableCollection<ViewModelBase>();
                }
                return _viewModels;
            }
        }
    }
}

MainWindowView.xaml

<Window x:Class="SidekickAdmin.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:SidekickAdmin.ViewModel"
        xmlns:vw="clr-namespace:SidekickAdmin.View"
        Title="Sidekick Admin" SizeToContent="WidthAndHeight">

    <!-- Typically done in a resources dictionary -->
    <Window.Resources>
        <ResourceDictionary Source="MainWindowResources.xaml" />
    </Window.Resources>


    <StackPanel>
        <ItemsControl ItemsSource="{Binding ViewModel}" Margin="3" /> 
    </StackPanel>

</Window>

MainWindowResources.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:vm="clr-namespace:SidekickAdmin.ViewModel"
                    xmlns:vw="clr-namespace:SidekickAdmin.View">

    <DataTemplate DataType="{x:Type vm:CompanyViewModel}">
        <vw:CompanyView />
    </DataTemplate>

</ResourceDictionary>

CompanyViewModel.cs (not really used yet as I am still trying to just get the view to appear)

namespace SidekickAdmin.ViewModel
{

    class CompanyViewModel : ViewModelBase
    {
        readonly GenericRepository _repository;

        #region Getters & Setters
        public ObservableCollection<Company> AllCompanies
        {
            get;
            private set;
        }

        #endregion

        #region Constructors
        public CompanyViewModel(GenericRepository repository)
        {

            if (repository == null)
            {
                throw new ArgumentNullException("repository");
            }

            _repository = repository;

            this.AllCompanies = new ObservableCollection<Company>(_repository.GetAll<Company>());
        }

        #endregion


        protected override void OnDispose()
        {
            this.AllCompanies.Clear();
        }

    }
}

CompanyView.xaml

<UserControl x:Class="SidekickAdmin.View.CompanyView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             Height="300" Width="300">

    <StackPanel>
        <TextBlock>You say Hello</TextBlock>
        <TextBlock>And I say Goodbye</TextBlock>    
        <TextBlock>Hello, Hello</TextBlock>
    </StackPanel>

 </UserControl>

Upvotes: 0

Views: 692

Answers (3)

John Papa
John Papa

Reputation: 22298

@RobertLevy and @dmusial are correct. You need to make your reference to ViewModels in your XAML plural, to match the property name in your C# code. Also, the property should be public, so the View can see it.

Upvotes: 1

dmusial
dmusial

Reputation: 1564

Besides what @Robert Levy has wrote, the error you are making is that your ViewModels property is private, make it public and it should work fine.

Upvotes: 3

Robert Levy
Robert Levy

Reputation: 29073

Lester's comment is right... you are binding to a ViewModel property which does not exist - MainWindowViewModel has a ViewModels property though. The s is important

Upvotes: 4

Related Questions