Search code examples
c#wpfdatacontext

how to use interface rather than concrete class to use as DataContext - wpf, autofac


I have below concrete class and interference,

public interface IMyViewModel
{
    ObservableCollection<Person> People { get; set; }
}

public class MyViewModel : INotifyPropertyChanged, IMyViewModel
{
    private ObservableCollection<Person> _people;
    public ObservableCollection<Person> People
    {
        get => _people;
        set
        {
            if (value == _people)
                return;

            _people = value;
            OnPropertyChanged();
        }
    }

    public MyViewModel()
    {
        _people = new ObservableCollection<Person>
        {
            new Person() {Id = 1, Name = "Bob", Age = 45},

        };
    }
} 

and using autofac for DI,

 builder.RegisterType<MyViewModel>().As<IMyViewModel>();

Now in my xaml file I am trying to bind a listview,

<ListView ItemsSource="{Binding People, Mode=OneWay}">
        <ListView.View>
            <GridView>
                <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name" Width="100"/>
                <GridViewColumn  Header="Age">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding Age}" Width="100"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>

In xaml code behind I want to use interface rather than concrete view model class, how to use this?

If I am using DataContext = _viewModel; then it's not works and no record bind to listview.

 public partial class NetworkConfiguration : Window
{
    private IMyViewModel _viewModel;

    public NetworkConfiguration()
    {
        InitializeComponent();

        //DataContext = new MyViewModel();

        DataContext = _viewModel;
    }

    public IMyViewModel ViewModel
    {
        get
        {
            return _viewModel;
        }
        set
        {
            DataContext = value;
            _viewModel = value;
        }
    }
}

Note - if I am using DataContext = new MyViewModel(); then it's work. how to user interface?

Thanks!


Solution

  •     public IMyViewModel ViewModel
        {
            get
            {
                return _viewModel;
            }
            set
            {
                DataContext = value;
                _viewModel = value;
            }
        }
    

    You need to actually assign the ViewModel with the value from your container:

    
          var builder = new ContainerBuilder();
          builder.RegisterType<MyViewModel>().As<IMyViewModel>();
    
          // This is your container, here you can get your instances from!
          Container = builder.Build();
    
          // Create the scope, resolve your interface,
          // use it, then dispose of the scope.
          using (var scope = Container.BeginLifetimeScope())
          {
             // get the vm from the container, assign it as datacontext.
             DataContext = scope.Resolve<IMyViewModel >();
    
          }