我正在使用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>
一切正常,我可以删除和添加新项目,编辑它们等。视图中的所有更改都会在ViewModel和Model中通过绑定和可观察对象自动反映,反之亦然。
但现在我需要将ToggleButton
添加到ItemsControl
的数据模板,该模板控制窗口其他部分中特定项目的可见性。我在ViewModel中需要IsChecked
值,因为窗口其他部分的控件是Windows窗体控件,如果没有ViewModel,我无法直接绑定IsChecked
。
但我不想在模型类(Foo,FooCollection)中添加新属性(例如,Visibility),因为它只是一个接口事物而且不需要保存或传递到ViewModel之外的某个地方。
所以我的问题:在ViewModel中向Model集合添加新属性的最佳方法是什么?
我可以在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
?
答案 0 :(得分:1)
添加属性的最佳位置当然是Foo
类。
创建另一个其他类型的集合,在当前集合中为每个Foo
对象添加一个对象,然后绑定到这个新对象的某个属性似乎是一个非常糟糕的解决方案,而不是简单地添加一个当前班级的财产。
Foo
不是&#34;接口的东西&#34;,或者至少它不应该是。视图模型应该包含视图绑定的属性。向其添加IsChecked
属性没有任何问题。这听起来肯定是您案例中的最佳解决方案。
答案 1 :(得分:0)
我不确定我是否理解为什么你需要在模型中添加属性。
您不能只使用命令属性或将EventTrigger添加到切换按钮吗? (参见Sega和Arseny对这两个例子的回答Executing a command on Checkbox.Checked or Unchecked)
这样,当您检查toggleButton时,viewModel中有一个方法可以启用或禁用Winform控件的visibility属性。
要从viewModel中的命令更改控件的可见性,可以使用MVVM LIGHT的messenger功能 MVVM Light Messenger - Sending and Registering Objects
ViewModel向您发送一条消息是Windows Forms,并且这个消息处理您的控件的可见性。