C# 绑定到MVVM中包含集合的模型
我刚开始使用MVVM(使用Caliburn.Micro),遇到了一个问题,我不确定我是否做得正确。我有一个modelC# 绑定到MVVM中包含集合的模型,c#,mvvm,collections,caliburn.micro,C#,Mvvm,Collections,Caliburn.micro,我刚开始使用MVVM(使用Caliburn.Micro),遇到了一个问题,我不确定我是否做得正确。我有一个modelMediaCacherConfig,它表示一个以json格式存储数据的文本文件。该模型包含两个字符串列表和一个字符串本身 我正在努力解决的是如何正确设置viewmodel,尤其是AddNewFolder()方法。我不确定是否引发了正确的事件以及viewmodel的表示是否正确。我可以看到如何绑定到一个简单的属性,但是绑定到一个集合似乎更像是一个头像,因为每次添加一个项(字符串)时,
MediaCacherConfig
,它表示一个以json格式存储数据的文本文件。该模型包含两个字符串列表和一个字符串本身
我正在努力解决的是如何正确设置viewmodel,尤其是AddNewFolder()
方法。我不确定是否引发了正确的事件以及viewmodel的表示是否正确。我可以看到如何绑定到一个简单的属性,但是绑定到一个集合似乎更像是一个头像,因为每次添加一个项(字符串)时,我都要创建一个全新的集合
此外,当我加载一个全新的模型时,我必须对所有对我没有意义的属性运行NotifyPropertyChanged()方法
非常感谢您的指导
public class MediaCacherConfig : IConfig
{
public string DatabaseFileName { get; set; }
public ICollection<string> FoldersToScan { get; set; }
public ICollection<string> ExtensionsToIgnore { get; set; }
}
以下是我的观点:
<UserControl x:Class="MediaCacher.Views.MediaCacherConfigView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="413" Width="300">
<Grid MinWidth="300" MinHeight="300" Background="LightBlue" Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="409*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<TextBox x:Name="DatabaseFileName" TextWrapping="Wrap" Margin="10,64,10,0" HorizontalAlignment="Center" Width="280" Height="42" VerticalAlignment="Top"/>
<ListBox x:Name="FoldersToScan" HorizontalAlignment="Left" Height="145" Margin="10,111,0,0" VerticalAlignment="Top" Width="280"/>
<ListBox x:Name="ExtensionsToIgnore" HorizontalAlignment="Left" Height="145" Margin="10,261,0,0" VerticalAlignment="Top" Width="280"/>
<Button x:Name="AddNewFolder" Content="Add" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="87" Height="49"/>
<Button x:Name="LoadConfig" Content="Load" HorizontalAlignment="Left" Margin="102,10,0,0" VerticalAlignment="Top" Width="96" Height="49"/>
<Button x:Name="SaveConfig" Content="Save" HorizontalAlignment="Left" Margin="203,10,0,0" VerticalAlignment="Top" Width="87" Height="49"/>
</Grid>
首先,您每次都会返回一个全新的收藏,因此显然没有任何东西会被保留下来
public BindableCollection<string> FoldersToScan
{
get
{
return new BindableCollection<string>(Model.FoldersToScan);
}
set
{
Model.FoldersToScan = value;
NotifyOfPropertyChange(() => FoldersToScan);
}
}
您建议如何从view->viewmodel->model提供BindableCollection的更改?理论上,您的模型也应该有一个BindableCollection,并且您的viewmodel只返回model.FoldersToScan。如果没有,您可以在“添加”文件夹中将项目添加到model.folders中,并引发列表更改事件,然后将其添加到viewmodel列表中。@Peter我添加了一些示例代码。它非常简单,只是用来给你一个想法。
public BindableCollection<string> FoldersToScan
{
get
{
return new BindableCollection<string>(Model.FoldersToScan);
}
set
{
Model.FoldersToScan = value;
NotifyOfPropertyChange(() => FoldersToScan);
}
}
public class YourViewModel
{
private readonly YourModel model;
private ObservableCollection<string> foldersToScan = new ObservableCollection<string>();
public ObservableCollection<string> FoldersToScan
{
get { return this.foldersToScan; }
}
public YourViewModel(YourModel model)
{
this.model = model;
this.model.OnItemAdded += item => this.foldersToScan.Add(item);
}
public void AddFolder(string addFolder) //gets called from view
{
this.model.AddFolder(addFolder); //could be ICommand using Command Pattern
}
}
public class YourModel
{
private readonly List<string> foldersToScan;
public IEnumerable<string> FoldersToScan
{
get { return this.foldersToScan; }
}
public event Action<string> OnItemAdded;
public YourModel()
{
this.foldersToScan = new List<string>();
}
public void AddFolder(string folder)
{
this.foldersToScan.Add(folder);
this.RaiseItemAdded(folder);
}
void RaiseItemAdded(string folder)
{
Action<string> handler = OnItemAdded;
if (handler != null) handler(folder);
}
}