Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ObservableCollection和存储库_C#_Wpf_Xaml_Mvvm_Windows 8 - Fatal编程技术网

C# ObservableCollection和存储库

C# ObservableCollection和存储库,c#,wpf,xaml,mvvm,windows-8,C#,Wpf,Xaml,Mvvm,Windows 8,我很难理解MVVM中可观察集合的概念。首先,我想指出,我是在Windows8/Metro应用程序中完成这项工作的,而不是WPF或Silverlight 根据microsoft文档,此集合具有以下用途: “表示动态数据收集,在添加、删除项目或刷新整个列表时提供通知。”据我所知,这在涉及绑定时对您有很大帮助。在网上,我找到了很多简单的例子,在运行时创建一个ObservableCollection,然后进行处理,但我没有找到将此集合与存储库一起使用的正确方法 假设我有以下存储库接口,它是ORM数据库后

我很难理解MVVM中可观察集合的概念。首先,我想指出,我是在Windows8/Metro应用程序中完成这项工作的,而不是WPF或Silverlight

根据microsoft文档,此集合具有以下用途: “表示动态数据收集,在添加、删除项目或刷新整个列表时提供通知。”据我所知,这在涉及绑定时对您有很大帮助。在网上,我找到了很多简单的例子,在运行时创建一个ObservableCollection,然后进行处理,但我没有找到将此集合与存储库一起使用的正确方法

假设我有以下存储库接口,它是ORM数据库后端的实现,或者是原始ADO.NET实现

public interface IRepository<T>
{
   ObservableCollection<T> GetAll();
   void Create();
   void Update();
   void Delete();
   T GetByKey(object key);
}
公共接口IRepository
{
ObservableCollection GetAll();
void Create();
无效更新();
作废删除();
T GetByKey(对象键);
}
以及一个简单的ViewModel,它使用存储库作为模型

public class ViewModel
{
   private ObservableCollection<Dummy> _obsListDummy;
   private RelayCommand _addCommand,_deleteCommand,_updateCommand;
   private IRepository<Dummy> _repositoryDummy;

   public class ViewModel()
   {
     _repositoryDummy=Factory.GetRepository<Dummy>();

   }  

   public ObservableCollection<Dummy> ObsListDummy
   {
     get
       {
          return _repositoryDummy.GetAll();
       }
   }

   public RelayCommand AddCommand
   {
     get
        {
           if (_addCommand == null)
       {
        _addCommand = new RelayCommand(p => DoAdd(); 
        //DoAdd method shows a popup for input dummy and then closes;
         );
       }
       return _myCommand;
        }

   }
   ........
}
公共类视图模型
{
私有可观测集合_oblistDummy;
私有RelayCommand _addCommand、_deleteCommand、_updateCommand;
私人i存款(u repositoryDummy);;
公共类ViewModel()
{
_repositoryDummy=Factory.GetRepository();
}  
公共可观测收集对象列表
{
得到
{
返回_repositoryDummy.GetAll();
}
}
公共RelayCommand AddCommand
{
得到
{
如果(_addCommand==null)
{
_addCommand=newrelayCommand(p=>DoAdd();
//DoAdd方法显示输入虚拟的弹出窗口,然后关闭;
);
}
返回_myCommand;
}
}
........
}
我的视图将是一个带有网格的简单XAML,并且虚拟对象已经实现了INotifyPropertyChanged

现在,在添加、更新或删除后使用此实现,ObservableCollection不会刷新,我知道我可以将IEnumerable改为IEnumerable,但我没有看到一个优雅的解决方案,可以让存储库与模型中的ObservableCollection同步,除了subscribing to CollectionChanged,在这里您处理所有状态,但在这里,我似乎会重复我自己以及我在存储库中所做的逻辑。更糟糕的是,假设我想从我的存储库中得到一些推送通知,推送到ObservableCollection

我希望我能理解我的问题


提前感谢。

您应该使用类型为
ObservableCollection
的成员来存储您的
虚拟视图模型。在
Initialize
方法中,从存储库中读取虚拟对象,创建
Dummy ViewModels
并将其放入
observateCollection
中。现在,当您使用
Binding
ObsListDummy
(并从该集合中添加/删除,还要注意绑定仅适用于公共属性)时,您的视图将得到更新

现在,每次读取时您都有一个新的
可观察集合
,不涉及任何事件,因此您的视图永远不会知道更改


此外,ViewModel应实现INotifyPropertyChanged

您应该在ViewModel上实现
INotifyPropertyChanged
,并且您的ObsListDummy属性应该将应用于集合的更改通知ViewModel。所以它应该是这样的:

public class ViewModel: INotifyPropertyChanged
{
    // Declare the event 
    public event PropertyChangedEventHandler PropertyChanged;

    // Create the OnPropertyChanged method to raise the event 
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    private ObservableCollection<Dummy> _dummyCollection;

    public ObservableCollection<Dummy> DummyCollection 
    {
        get { return _dummyCollection; }
        set
        {
            // Set the value and then inform the ViewModel about change with OnPropertyChanged
            _dummyCollection = value;
            OnPropertyChanged("DummyCollection");
        }
    }
}
公共类视图模型:INotifyPropertyChanged
{
//宣布事件
公共事件属性更改事件处理程序属性更改;
//创建OnPropertyChanged方法以引发事件
受保护的void OnPropertyChanged(字符串名称)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
{
处理程序(此,新PropertyChangedEventArgs(名称));
}
}
私人可观测集合(dummyCollection);;
公共可观测集合DummyCollection
{
获取{return\u dummyCollection;}
设置
{
//设置该值,然后使用OnPropertyChanged通知ViewModel有关更改的信息
_dummyCollection=值;
不动产变更(“DummyCollection”);
}
}
}

整个
INotifyPropertyChanged
接口和实现包括一些脏活,例如声明事件和创建一个帮助器方法来引发事件,因此我建议您使用一些库来进行类似操作。

这不会解决问题,因为他总是返回一个新集合,并且不包含任何成员。他应该使用该成员进行绑定,而不是返回新的repository.readall()。ObservableCollection处理项目本身的添加/删除。请看一下我的答案,我想我已经解释过了。对不起,我不明白。如果回购每次都返回一个新集合,为什么视图不会被通知?如果将新值(可以是null、空集合或任何内容)分配给属性,并且该属性调用OnPropertyChanged,视图将知道它。好的,如果使用该属性,它可能会工作。但是,如果总是在没有项目发生更改的情况下查询存储库,那就太过分了。只需初始化它一次,让集合完成它的工作,一切都正常。