Loading UserControl to ItemsControl with MVVM

itemscontrol, mvvm, user-controls, wpf

Solution

You are overwriting the `DataContext` of your `UserControl` by setting it in the constructor of your `UserControl` after calling `InitializeComponent();`

By default, the `ItemsControl` will create an `ItemTemplate` for each item in the collection, and set it's `DataContext` to the item from the `ItemsSource`. The end result will be three new `my:BackUpControl` objects, with the `DataContext` behind those objects bound to the `BackUpControlViewModel` from `ItemsControl.ItemsSource`

Remove the line `this.DataContext = new BackUpControlViewModel();` from your UserControl's constructor, and it should work like you expect

Problem

I have a UserControl which I would like to load multiple times on my MainWindow. For this I use an `ItemsControl`: ``` <ItemsControl Grid.Row="1" ItemsSource="{Binding FtpControlList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal" IsItemsHost="True" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate DataType="{x:Type my:BackUpControl}"> <my:BackUpControl Margin="5" Width="500" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> ``` My UserControl is bound by a ViewModel. My MainWindow also has a ViewModel. In the MainWindowViewModel I have an OberservableCollection dependency property which houlds a list of my UserControlViewModels. In the constructor of the MainWindowViewModel I add some UserControlViewModels to the List. ``` public MainWindowViewModel() { FtpControlList = new ObservableCollection<BackUpControlViewModel>(); FtpControlList.Add(new BackUpControlViewModel("View 1")); FtpControlList.Add(new BackUpControlViewModel("View 2")); FtpControlList.Add(new BackUpControlViewModel("View 3")); } public static readonly DependencyProperty FtpControlListProperty = DependencyProperty.Register("FtpControlList", typeof(ObservableCollection<BackUpControlViewModel>), typeof(MainWindowViewModel)); public ObservableCollection<BackUpControlViewModel> FtpControlList { get { return (ObservableCollection<BackUpControlViewModel>)GetValue(FtpControlListProperty); } set { SetValue(FtpControlListProperty, value); } } ``` Now for some reason it loads 3 times an empty usercontrol and NOT the ones in the FtpControlList property withe the property set to 'View 1, View 2 and View 3'. How can I make sure that the UserControls from the list are loaded and not empty ones? Part of the UserControlViewModel: ``` // part of the UserControl Viewmodel public BackUpControlViewModel() { } public BackUpControlViewModel(string header) { GroupBoxHeader = header; } #region Dependency Properties public static readonly DependencyProperty GroupBoxHeaderProperty = DependencyProperty.Register("GroupBoxHeader", typeof(string), typeof(BackUpControlViewModel), new UIPropertyMetadata("empty")); public string GroupBoxHeader { get { return (string)GetValue(GroupBoxHeaderProperty); } set { SetValue(GroupBoxHeaderProperty, value); } } public static readonly DependencyProperty FtpUrlProperty = DependencyProperty.Register("FtpUrl", typeof(string), typeof(BackUpControlViewModel), new UIPropertyMetadata("ftpurl")); public string FtpUrl { get { return (string)GetValue(FtpUrlProperty); } set { SetValue(FtpUrlProperty, value); } } public static readonly DependencyProperty FtpUserProperty = DependencyProperty.Register("FtpUser", typeof(string), typeof(BackUpControlViewModel), new UIPropertyMetadata("ftpUser")); public string FtpUser { get { return (string)GetValue(FtpUserProperty); } set { SetValue(FtpUserProperty, value); } } #endregion ``` It will probably be something stupid but I can't seem to find it. The datacontext for MainWindow and the UserControl are bound to it's Viewmodel. EDIT: BackupControl datacontext set to BackupControlViewModel (to answer Rachel's question) ``` public partial class BackUpControl : UserControl { public BackUpControl() { InitializeComponent(); this.DataContext = new BackUpControlViewModel(); } } ```

Original source