Это мой первый вопрос. Я упростил свой код как можно больше, чтобы проиллюстрировать, что я ищу.Bind ItemsСвяжитесь с коллекцией ViewModels на ViewModel
У меня есть ViewModel (внешний), который содержит ObservableCollection другого ViewModel (внутренний). Внутренняя ViewModel предназначена для UserControl. Внешний ViewModel предназначен для MainWindow. Я просто хочу отображать один UserControl для каждого элемента в ObservableCollection. Но у меня возникли проблемы с набором DataContext UserControl для элементов в ObservableCollection.
Внутренний ViewModel (для UserControl):
public class InnerViewModel : ViewModelBase
{
string _text;
public string Text
{
get { return _text; }
set { SetProperty<string>(ref _text, value); }
}
public InnerViewModel() { }
}
Внутренний ViewModel (для UserControl):
public class OuterViewModel : ViewModelBase
{
ObservableCollection<InnerViewModel> _innerViewModels;
public ObservableCollection<InnerViewModel> InnerViewModels
{
get { return _innerViewModels; }
set { SetProperty<ObservableCollection<InnerViewModel>>(ref _innerViewModels, value); }
}
public OuterViewModel()
{
_innerViewModels = new ObservableCollection<InnerViewModel>();
}
public void Init()
{
InnerViewModels.Clear();
InnerViewModels.Add(new InnerViewModel { Text = "Item1" });
InnerViewModels.Add(new InnerViewModel { Text = "Item2" });
}
}
InnerControl XAML (внешний тег удален для чистоты)
<UserControl.DataContext>
<local:InnerViewModel />
</UserControl.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50px"></ColumnDefinition>
<ColumnDefinition ></ColumnDefinition>
<ColumnDefinition Width="50px"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Content="Header"></Label>
<Label Grid.Column="1" Content="{Binding Text}" ></Label>
<Label Grid.Column="2" Content="Footer"></Label>
</Grid>
MainWindow XAML
<Window.DataContext>
<local:OuterViewModel />
</Window.DataContext>
<Grid>
<ItemsControl ItemsSource="{Binding InnerViewModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:InnerControl></local:InnerControl> <!-- HOW DO I SET THE DATACONTEXT ON THIS??? -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
InnerControl.cs Код:
public partial class InnerControl : UserControl
{
public InnerControl()
{
InitializeComponent();
}
}
MainWindow.cs Код:
public partial class MainWindow : Window
{
OuterViewModel _vm;
public MainWindow()
{
InitializeComponent();
_vm = (OuterViewModel)DataContext;
_vm.Init();
}
}
ViewModelBase:
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
{
if (Equals(storage, value))
{
return false;
}
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Результат: Screenshot of what I get when I run
Сначала вы смешиваете view-first с view-model-first, это не сработает.Лично я думаю, что view-first - это фигня, похоже, создает всевозможные ненужные проблемы. –