我有一个填充了整数的组合框。如果我选择三个,我想在它旁边显示 3 个文本框。如果我选择 2,我想显示 2。 在文本框中,我写下示例编号:123、943、1e4 等。
文件.xaml
<ComboBox ItemsSource="{x:Bind ViewModel.SamplesCountList, Mode=OneTime}"
SelectedItem="{x:Bind ViewModel.SamplesCount, Mode=TwoWay}" />
<ItemsControl ItemsSource="{x:Bind Path=ViewModel.SamplesCollection, Mode=TwoWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我使用 MVVM Light。我有一个视图模型,其中包含来自业务层的模型。SamplesCollection
链接到ItemsControl
。如果我更新可观察列表,它会生成动态文本框。这很好。
视图模型.cs
public class MyModelViewModel : ObservableRecipient
{
private MyModelModel _myModelModel = new MyModelModel();
public MyModelModel MyModelModel
{
get { return _myModelModel; }
set { SetProperty(ref _myModelModel, value); }
}
public ObservableCollection<string> SamplesCollection { get; set; } = new ObservableCollection<string>();
public CreateFile() {
// Take _myModelModel and create text file based on its fields
}
}
在其他部分中,我只是将我的业务模型直接链接到 xaml 中的文本框。 像这样ItemsSource="{x:Bind Path=MyViewModel.MyModel.Id, Mode=TwoWay}
我不能用这个动态的 ItemsControl<->ComboBox 执行此操作,因为它不会检测到创建文本框的更改,因为ItemsSource="{x:Bind Path=MyViewModel.MyModel.SamplesCollectionModel}
,SamplesCollectionModel
是业务层中的List<string>
。
问题:我应该在需要处理它时只获取我的可观察 SamplesCollection.ToList() 并将其分配给我的_myModel,还是我可以以某种方式将我的业务模型与 xaml 代码链接以摆脱这个额外的可观察集合字段?这里的最佳实践是什么?
我建议你在ViewModel中完成工作,而不是试图改变商业模式。这是因为您使用的是 MVVM 模式,并且模型层应只保留您的业务数据。
有关详细信息,请查看:数据绑定和 MVVM。
更新:
@Mihai Socaciu在这里找到了Github示例: Windows-appsample-customers-orders-database.它包含针对此类方案的解决方案,所有详细代码都列在那里。
基本上代码如下所示:
public class OrderViewModel
{
private ObservableCollection<LineItem> _lineItems;
public ObservableCollection<LineItem> LineItems
{
get => _lineItems;
set
{
if (_lineItems != value)
{
if (value != null)
{
value.CollectionChanged += LineItems_Changed;
}
if (_lineItems != null)
{
_lineItems.CollectionChanged -= LineItems_Changed;
}
_lineItems = value;
}
}
}
public OrderViewModel()
{
LineItems = new ObservableCollection<LineItem>(Model.LineItems);
LineItems.CollectionChanged += LineItems_Changed;
}
private void LineItems_Changed(object sender, NotifyCollectionChangedEventArgs e)
{
if (LineItems != null)
{
Model.LineItems = LineItems.ToList();
}
}
}