2017-06-14 77 views
-1

我有一组类用于将JSON反序列化到。我的程序会定期查找这个JSON文件的变化,如果发现任何变化,它会使用反射将新数据推送到这些类的属性中。获取新项目添加到自定义类的Observable集合

成功更新后,我需要找到任何添加到Item2类(SocialExportJSON.SocialExportData.Item2)集合中的新项目。

我的JSON类看起来像这样(有更多的,但我想避免的代码太大的墙):

public class Item2 : INotifyPropertyChanged 
{ 
    [JsonProperty("type")] 
    private string type; 

    public string Type 
    { 
     get 
     { 
      return type; 
     } 
     set 
     { 
      if (type != value) 
      { 
       type = value; 
       RaisePropertyChanged("Type"); 
      } 
     } 
    } 

    [JsonProperty("id")] 
    private string id; 

    public string ID 
    { 
     get 
     { 
      return id; 
     } 
     set 
     { 
      if (id != value) 
      { 
       id = value; 
       RaisePropertyChanged("ID"); 
      } 
     } 
    } 

    [JsonProperty("postedIso8601")] 
    private string postedIso8601; 

    public string PostedIso8601 
    { 
     get 
     { 
      return postedIso8601; 
     } 
     set 
     { 
      if (postedIso8601 != value) 
      { 
       postedIso8601 = value; 
       RaisePropertyChanged("PostedIso8601"); 
      } 
     } 
    } 

    [JsonProperty("postedTimestamp")] 
    private object postedTimestamp; 

    public object PostedTimestamp 
    { 
     get 
     { 
      return postedTimestamp; 
     } 
     set 
     { 
      if (postedTimestamp != value) 
      { 
       postedTimestamp = value; 
       RaisePropertyChanged("PostedTimestamp"); 
      } 
     } 
    } 

    [JsonProperty("engagement")] 
    private Engagement engagement; 

    public Engagement Engagement 
    { 
     get 
     { 
      return engagement; 
     } 
     set 
     { 
      if (engagement != value) 
      { 
       engagement = value; 
       RaisePropertyChanged("Engagement"); 
      } 
     } 
    } 

    [JsonProperty("source")] 
    private Source2 source; 

    public Source2 Source 
    { 
     get 
     { 
      return source; 
     } 
     set 
     { 
      if (source != value) 
      { 
       source = value; 
       RaisePropertyChanged("Source"); 
      } 
     } 
    } 

    [JsonProperty("author")] 
    private Author author; 

    public Author Author 
    { 
     get 
     { 
      return author; 
     } 
     set 
     { 
      if (author != value) 
      { 
       author = value; 
       RaisePropertyChanged("Author"); 
      } 
     } 
    } 

    [JsonProperty("content")] 
    private Content content; 

    public Content Content 
    { 
     get 
     { 
      return content; 
     } 
     set 
     { 
      if (content != value) 
      { 
       content = value; 
       RaisePropertyChanged("Content"); 
      } 
     } 
    } 

    [JsonProperty("location")] 
    private Location location; 

    public Location Location 
    { 
     get 
     { 
      return location; 
     } 
     set 
     { 
      if (location != value) 
      { 
       location = value; 
       RaisePropertyChanged("Location"); 
      } 
     } 
    } 

    [JsonProperty("publication")] 
    private Publication publication; 

    public Publication Publication 
    { 
     get 
     { 
      return publication; 
     } 
     set 
     { 
      if (publication != value) 
      { 
       publication = value; 
       RaisePropertyChanged("Publication"); 
      } 
     } 
    } 

    [JsonProperty("metadata")] 
    private Metadata metadata; 

    public Metadata Metadata 
    { 
     get 
     { 
      return metadata; 
     } 
     set 
     { 
      if (metadata != value) 
      { 
       metadata = value; 
       RaisePropertyChanged("Metadata"); 
      } 
     } 
    } 

    //Event handling 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void RaisePropertyChanged(string property) 
    { 
     //Console.WriteLine("Updated"); 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); 
    } 
} 

public class SocialExportData : INotifyPropertyChanged 
{ 
    [JsonProperty("dataType")] 
    private string dataType; 

    public string DataType 
    { 
     get 
     { 
      return dataType; 
     } 
     set 
     { 
      if (dataType != value) 
      { 
       dataType = value; 
       RaisePropertyChanged("DataType"); 
      } 
     } 
    } 

    [JsonProperty("id")] 
    private int id; 

    public int ID 
    { 
     get 
     { 
      return id; 
     } 
     set 
     { 
      if (id != value) 
      { 
       id = value; 
       RaisePropertyChanged("ID"); 
      } 
     } 
    } 

    [JsonProperty("story")] 
    private Story story; 

    public Story Story 
    { 
     get 
     { 
      return story; 
     } 
     set 
     { 
      if (story != value) 
      { 
       story = value; 
       RaisePropertyChanged("Story"); 
      } 
     } 
    } 

    [JsonProperty("order")] 
    private string order; 

    public string Order 
    { 
     get 
     { 
      return order; 
     } 
     set 
     { 
      if (order != value) 
      { 
       order = value; 
       RaisePropertyChanged("Order"); 
      } 
     } 
    } 

    [JsonProperty("lifetime")] 
    private string lifetime; 

    public string Lifetime 
    { 
     get 
     { 
      return lifetime; 
     } 
     set 
     { 
      if (lifetime != value) 
      { 
       lifetime = value; 
       RaisePropertyChanged("Lifetime"); 
      } 
     } 
    } 

    [JsonProperty("maxAge")] 
    private int maxAge; 

    public int MaxAge 
    { 
     get 
     { 
      return maxAge; 
     } 
     set 
     { 
      if (maxAge != value) 
      { 
       maxAge = value; 
       RaisePropertyChanged("MaxAge"); 
      } 
     } 
    } 

    [JsonProperty("maxSize")] 
    private int maxSize; 

    public int MaxSize 
    { 
     get 
     { 
      return maxSize; 
     } 
     set 
     { 
      if (maxSize != value) 
      { 
       maxSize = value; 
       RaisePropertyChanged("MaxSize"); 
      } 
     } 
    } 

    [JsonProperty("consumeCount")] 
    private int consumeCount; 

    public int ConsumeCount 
    { 
     get 
     { 
      return consumeCount; 
     } 
     set 
     { 
      if (consumeCount != value) 
      { 
       consumeCount = value; 
       RaisePropertyChanged("ConsumeCount"); 
      } 
     } 
    } 

    [JsonProperty("consumeInterval")] 
    private int consumeInterval; 

    public int ConsumeInterval 
    { 
     get 
     { 
      return consumeInterval; 
     } 
     set 
     { 
      if (consumeInterval != value) 
      { 
       consumeInterval = value; 
       RaisePropertyChanged("ConsumeInterval"); 
      } 
     } 
    } 

    [JsonProperty("items")] 
    private ObservableCollection<Item2> items; 

    public ObservableCollection<Item2> Items 
    { 
     get 
     { 
      return items; 
     } 
     set 
     { 
      if (items != value) 
      { 
       items = value; 
       RaisePropertyChanged("Items"); 
      } 
     } 
    } 

    //Event handling 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void RaisePropertyChanged(string property) 
    { 
     //Console.WriteLine("Updated"); 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); 
    } 
} 

public class SocialExportJSON : INotifyPropertyChanged 
{ 
    [JsonProperty("id")] 
    private string id; 

    public string ID 
    { 
     get 
     { 
      return id; 
     } 
     set 
     { 
      if (id != value) 
      { 
       id = value; 
       RaisePropertyChanged("ID"); 
      } 
     } 
    } 

    [JsonProperty("ttl")] 
    private int ttl; 

    public int TTL 
    { 
     get 
     { 
      return ttl; 
     } 
     set 
     { 
      if (ttl != value) 
      { 
       ttl = value; 
       RaisePropertyChanged("TTL"); 
      } 
     } 
    } 

    [JsonProperty("serial")] 
    private long serial; 

    public long Serial 
    { 
     get 
     { 
      return serial; 
     } 
     set 
     { 
      if (serial != value) 
      { 
       serial = value; 
       RaisePropertyChanged("Serial"); 
      } 
     } 
    } 

    [JsonProperty("formatType")] 
    private string formatType; 

    public string FormatType 
    { 
     get 
     { 
      return formatType; 
     } 
     set 
     { 
      if (formatType != value) 
      { 
       formatType = value; 
       RaisePropertyChanged("FormatType"); 
      } 
     } 
    } 

    [JsonProperty("modifiedIso8601")] 
    private string modifiedIso8601; 

    public string ModifiedIso8601 
    { 
     get 
     { 
      return modifiedIso8601; 
     } 
     set 
     { 
      if (modifiedIso8601 != value) 
      { 
       modifiedIso8601 = value; 
       RaisePropertyChanged("ModifiedIso8601"); 
      } 
     } 
    } 

    [JsonProperty("modifiedTimestamp")] 
    private long modifiedTimestamp; 

    public long ModifiedTimestamp 
    { 
     get 
     { 
      return modifiedTimestamp; 
     } 
     set 
     { 
      if (modifiedTimestamp != value) 
      { 
       modifiedTimestamp = value; 
       RaisePropertyChanged("ModifiedTimestamp"); 
      } 
     } 
    } 

    [JsonProperty("timezone")] 
    private string timezone; 

    public string Timezone 
    { 
     get 
     { 
      return timezone; 
     } 
     set 
     { 
      if (timezone != value) 
      { 
       timezone = value; 
       RaisePropertyChanged("Timezone"); 
      } 
     } 
    } 

    [JsonProperty("dataType")] 
    private string dataType; 

    public string DataType 
    { 
     get 
     { 
      return dataType; 
     } 
     set 
     { 
      if (dataType != value) 
      { 
       dataType = value; 
       RaisePropertyChanged("DataType"); 
      } 
     } 
    } 

    [JsonProperty("exports")] 
    private ObservableCollection<SocialExportData> exports; 

    public ObservableCollection<SocialExportData> Exports 
    { 
     get 
     { 
      return exports; 
     } 
     set 
     { 
      if (exports != value) 
      { 
       exports = value; 
       RaisePropertyChanged("Exports"); 
      } 
     } 
    } 

    //Event handling 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void RaisePropertyChanged(string property) 
    { 
     //Console.WriteLine("Updated"); 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); 
    } 
} 

在另一类,我要反序列化的全局实例的方法我JSON类。它看起来像这样:

public SocialExportJSON socialExportData; 

    private async void DownloadAndDeserializeJSONAsync() 
    { 
     try 
     { 
      //Create a web client with the supplied credentials 
      var exportClient = new WebClient { Credentials = new NetworkCredential(uName, pw), Encoding = Encoding.UTF8}; 

      //Create a task to download the JSON string and wait for it to finish 
      var downloadTask = Task.Run(() => exportClient.DownloadString(new Uri(eURL))); 
      downloadTask.Wait(); 

      //Get the string from the task 
      var JSONString = await downloadTask; 

      //Create a task to deserialize the JSON from the last task 
      var DeserializeTask = Task.Run(() => JsonConvert.DeserializeObject<SocialExportJSON>(JSONString)); 
      DeserializeTask.Wait(); 

      SocialExportJSON sej = await DeserializeTask; 

      //Check the timestamp first to see if we should change the data 
      if(socialExportData == null) 
      { 
       //Get the data from the task 
       socialExportData = await DeserializeTask; 
      } 
      else if(sej.ModifiedTimestamp != socialExportData.ModifiedTimestamp) 
      { 
       //Get the data from the task 
       SocialExportJSON newData = await DeserializeTask; 
       GetNewItems(newData); 
       SetNewData(newData); 

       //Call the exportUpdated event when the task has finished 
       exportUpdated(); 
      } 
     } 
     catch (Exception e) 
     { 
      MessageBox.Show(e.Message.ToString()); 
     } 
    } 

在我SetNewData功能,如下图所示,我使用反射来设置我的世界级的性能。因为我设置的是整个集合而不是遍历每个类中的每个属性,所以我无法使用CollectionChanged事件来查找新项目。

public void SetNewData(SocialExportJSON newData) 
    { 
     //Loop through each of the properties and copy from source to target 
     foreach (PropertyInfo pi in socialExportData.GetType().GetProperties()) 
     { 
      if (pi.CanWrite) 
      { 
       pi.SetValue(socialExportData, pi.GetValue(newData, null), null); 
      } 
     } 
    } 

有没有一种方法可以修改我的SetNewData函数以调用CollectionChanged?如果不是的话,那么对于我的Item2集合中添加任何新增功能,最好的方法是什么?

+1

哪一个是你的“全球班”,你如何在你的应用中使用它? – mm8

+0

我有我的根JSON类SocialExportJSON的全局实例。我用它来访问我的应用程序中反序列化的所有JSON数据。 – Luke4792

+1

因此,您正在创建SocialExportJSON的新实例,并期待准确发生什么......?你在说什么ObservableCollection和对象实例? – mm8

回答

1

在我的主要功能。我创建了一个名为SocialExport我的类的实例,像这样:

SocialExport s = new SocialExport("http://example.json", "example", "example");. 

这个类是我的JSON类的全局实例包含,和我的事件处理程序被添加像这样

s.socialExportData.Exports[0].Items.CollectionChanged += CollectionChanged; 

然后,您正在为CollectionChanged事件挂接事件处理程序,该特定实例ObservableCollection<Item2>

如果你创建一个新的ObservableCollection<Item2>,你显然必须把一个事件处理程序连接到这个。当新项目添加到新实例时,不会调用与旧对象关联的事件处理程序。

因此,无论何时创建新的ObservableCollection<Item2>,使用或不使用反序列化,您应该挂钩一个新的事件处理程序。

你可以在你的DownloadAndDeserializeJSONAsync方法中做到这一点。另一种选择是只创建一个集合实例,并从这个实例中删除和添加项目。

+0

我不认为这是问题。由于在我的'SocialExport'类(即'socialExportData')中有一个JSON类的全局实例,我的数据总是被设置为JSON类的同一个实例,新数据只是覆盖类的属性(参见我的' SetNewData'函数)。我认为问题在于,因为我直接设置了根类的属性,子类“SocialExportData”的'ObservableCollection '属性没有按照它应该的方式进行更新,但我不知道如何解决这个问题。 – Luke4792

+1

DeserializeTask方法返回一个* new * SocialExportJSON,不是吗?所以这是问题。或者至少有一部分。 – mm8

+0

不,不是,我为新数据创建了一个临时'SocialExportJSON',然后将已创建的全局实例的属性设置为临时实例的属性。这在'SetNewData'方法中完成。 – Luke4792

相关问题