interface ICar
{
UserControl SmallView{ get; }
UserControl CompleteView{ get; }
}
class ViewModel
{
ObservableCollection<ICar> Cars{ get; set;}
ObservableCollection<UserControl> SmallViews{ get; }
ObservableCollection<UserControl> CompleteViews{ get; }
}
XAML
<ItemControl ItemsSource="{Binding SmallViews}"/>
<ItemControl ItemsSource="{Binding CompleteView}"/>
我正在向ViewModel.Cars集合添加ICars实例。当发生这种情况时,我希望在View(XAML)中添加两个UserControls(小和完整)。
- 我可以通过在Cars.CollectionChanged被提升时在CodeBehind中设置ItemsSource来让它按照我的意愿工作。但我担心所有的集合都会重新绘制到ItemsSource中的所有项目。我只想添加更改,我希望优雅的解决方案没有很多CodeBehind。
这个Codebehind使它按预期工作 - 但我想要一些更清洁的东西与真正的绑定。 CompleteControls和SmallControls是上面ItemControls的名称,在此解决方案中没有绑定标记:-(。
public CarsView(ViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
UpdateViews(viewModel.Cars);
viewModel.Cars.CollectionChanged += (caller, args) =>
UpdateViews(args.NewItems.Cast<ICar>());
}
private void UpdateViews(IEnumerable<ICar> newCars)
{
foreach (var car in newCars)
{
CompleteControls.Items.Add(car.CompleteView);
SmallControls.Items.Add(car.SmallView);
}
}
答案 0 :(得分:0)
我在你的概念中看到了一些缺陷。
class ViewModel
{
ObservableCollection<ICar> Cars{ get; set;}
// This is wrong for MVVM. You don't need this.
//
// ObservableCollection<UserControl> SmallViews{ get; }
// ObservableCollection<UserControl> CompleteViews{ get; }
}
它也将摆脱这一点。
UpdateViews(viewModel.Cars);
viewModel.Cars.CollectionChanged += (caller, args) =>
UpdateViews(args.NewItems.Cast<ICar>());
关于ObvservableCollection,您需要了解两件事。
我看到你来自Winforms。首先检查有关MVVM的更多信息。它会很快得到回报。你需要记住,如果你在控件背后的代码中做任何事情,停止这样做,导致你做错了。 您将在XAML中实例化UserControl。
<Listbox ItemsSource={Binding Cars}>
<Listbox.ItemsTemplate>
<DataTemplate>
<StackPanel>
<my:SmallViews />
<my:CompleteViews />
</StackPanel>
</DataTemplate>
</Listbox.ItemsTemplate>
</Listbox>
你应该真的避免处理
背后的代码中的任何UI元素