【发布时间】:2018-02-07 19:13:38
【问题描述】:
我正在使用 MVVM Light 编写具有 MVVM 结构的 WPF 应用程序。
我在模型中有 Foo 类:
class Foo: ObservableObject
{
private string _propA = String.Empty;
public string PropA
{
get => _propA ;
set
{
if (_propA == value)
{
return;
}
_propA = value;
RaisePropertyChanged("PropA");
}
}
// same for property PropB, PropC, PropD, etc.
}
我在模型中有一些Foo 对象的集合:
class FooCollection: ObservableObject
{
private ObservableCollection<Foo> _items = null;
public IEnumerable<Foo> Items
{
get { ... }
set { ... }
}
public string Name { get; set; }
// ...
// and other methods, properties and fields
}
现在我有一个 ViewModel,这个列表是通过一些注入的提供者填充的:
class MainWindowModel: ViewModelBase
{
private FooCollection _fooList;
public FooList
{
get => _fooList;
set
{
_fooList = value;
RaisePropertyChangedEvent(FooList);
}
}
public MainWindowModel(IFooListProvider provider)
{
FooList = provider.GetFooList();
}
}
还有视图,以MainWindowModel 作为数据上下文:
<TextBlock Text={Binding FooList.Name} />
<ItemsControl ItemsSource="{Binding FooList.Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text={Binding PropA} />
<Button Content={Binding PropB} />
<!-- other controls with bindings -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
一切正常,我可以删除和添加新项目,编辑它们等等。View 中的所有更改都会通过绑定和可观察对象自动反映在 ViewModel 和 Model 中,反之亦然。
但现在我需要将ToggleButton 添加到ItemsControl 的数据模板中,该模板控制特定项目在窗口其他部分的可见性。我需要 ViewModel 中的IsChecked 值,因为窗口其他部分的控件是 Windows 窗体控件,我无法在没有 ViewModel 的情况下直接绑定IsChecked。
但我不想在模型类(Foo、FooCollection)中添加新属性(例如 Visibility),因为它只是一个接口的东西,不需要保存或传递到 ViewModel 之外的某个地方。
所以我的问题是:在 ViewModel 中向模型集合添加新属性的最佳方式是什么?
我可以在 ViewModel 中创建新的包装器集合(某种class Wrapper { Foo item, bool Visibility })并将其绑定到ItemsControl。但在这种情况下,我必须手动控制添加、删除和编辑,并将所有更改从List<Wrapper> 转移到FooList.Items,所以我不喜欢这个解决方案。有没有更简单的方法来实现这一点?
澄清问题的版本。现在我有:
<ItemsControl ItemsSource="{Binding FooList.Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text={Binding PropA} />
<Button Content={Binding PropB} />
<ToggleButton IsChecked={Binding ????????????} />
<!-- other controls with bindings -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我在类中没有绑定IsChecked 的字段,我不想将它添加到类中,因为它只是接口的东西而不是数据模型字段。例如,我如何创建另一个 bool 集合并将其绑定到此 ItemControl 以及 FooList.Items?
【问题讨论】:
-
要绑定的 IsChecked 属性在哪里定义...?
-
如何在 WinForms 控件中绑定/填充
FooList.Items? -
@SeeSharpCode 我不绑定它。 WinForms 控件是旧的 3D 可视化控件 (VTK)。
-
@mm8 这就是问题所在。如果我不能在
Foo类中定义它,我应该在哪里定义它以及如何绑定它。 -
你应该在 Foo 类中定义它。看我的回答。 Foo 不应被视为“接口事物”。那是你的问题。
标签: wpf mvvm collections binding