C# 绑定到MVVM中包含集合的模型

C# 绑定到MVVM中包含集合的模型,c#,mvvm,collections,caliburn.micro,C#,Mvvm,Collections,Caliburn.micro,我刚开始使用MVVM(使用Caliburn.Micro),遇到了一个问题,我不确定我是否做得正确。我有一个modelMediaCacherConfig,它表示一个以json格式存储数据的文本文件。该模型包含两个字符串列表和一个字符串本身 我正在努力解决的是如何正确设置viewmodel,尤其是AddNewFolder()方法。我不确定是否引发了正确的事件以及viewmodel的表示是否正确。我可以看到如何绑定到一个简单的属性,但是绑定到一个集合似乎更像是一个头像,因为每次添加一个项(字符串)时,

我刚开始使用MVVM(使用Caliburn.Micro),遇到了一个问题,我不确定我是否做得正确。我有一个model
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);
        }
    }