2015-11-19 67 views
2

我有一個ObservableCollection項目,我需要能夠更新並使用ICollectionView來表示數據。錯誤:這種類型的CollectionView不支持對其SourceCollection的更改

下面是相關的代碼位:

private ObservableCollection<Hero> heroesDBHeroes; 
public ObservableCollection<Hero> HeroesDBHeroes 
{ 
    get 
    { 
     return heroesDBHeroes; 
    } 
    set 
    { 
     heroesDBHeroes = value; 
     OnPropertyChanged("HeroesDBHeroes"); 
    } 
} 
private void HeroesDBAddHeroes() 
{ 
    if(HeroesDBHeroes != null) 
    { 
     HeroesDBHeroes.Clear(); 
    } 
    HeroesDBHeroes = Hero.GetAllHeroes(); 

    HeroesDBFilteredHeroes = new ListCollectionView(HeroesDBHeroes); 
    HeroesDBFilteredHeroes.Filter = new Predicate<object>(HeroesDBFilterHeroes); 
    HeroesDBFilteredHeroes.Refresh(); 
    OnPropertyChanged("HeroesDBFilteredHeroes"); 
} 

這裏是的CollectionView與它的過濾:

public CollectionView HeroesDBFilteredHeroes { get; set; } 
    public bool HeroesDBFilterHeroes(object item) 
    { 
     Hero h = item as Hero; 
     bool ID, Name, GoldMinimum, GoldMaximum, PlatinumMinimum, PlatinumMaximum, DBTag, ReleaseDateStart, ReleaseDateEnd, Available, Sale, Featured, New, F2P, Homepage, Thumbnail, FeaturedThumbnail, ShortDescription, Description; 

     ID = Name = GoldMinimum = GoldMaximum = PlatinumMinimum = PlatinumMaximum = DBTag = ReleaseDateStart = ReleaseDateEnd = Available = Sale = Featured = New = F2P = Homepage = Thumbnail = FeaturedThumbnail = ShortDescription = Description = false; 

     if (h == null) 
     { 
      return false; 
     } 

     if (HeroesDBFilterID == null || HeroesDBFilterID == h.ID) 
     { 
      ID = true; 
     } 

     if (HeroesDBFilterName == "" || h.Name.IndexOf(HeroesDBFilterName, 0, StringComparison.CurrentCultureIgnoreCase) != -1) 
     { 
      Name = true; 
     } 

     if (HeroesDBFilterGoldMinimum == null || HeroesDBFilterGoldMinimum <= h.Gold) 
     { 
      GoldMinimum = true; 
     } 

     if (HeroesDBFilterGoldMaximum == null || HeroesDBFilterGoldMaximum >= h.Gold) 
     { 
      GoldMaximum = true; 
     } 

     if (HeroesDBFilterPlatinumMinimum == null || HeroesDBFilterPlatinumMinimum <= h.Platinum) 
     { 
      PlatinumMinimum = true; 
     } 

     if (HeroesDBFilterPlatinumMaximum == null || HeroesDBFilterPlatinumMaximum >= h.Platinum) 
     { 
      PlatinumMaximum = true; 
     } 

     if (HeroesDBFilterDBTag == "" || h.DBTag.IndexOf(HeroesDBFilterDBTag, 0, StringComparison.CurrentCultureIgnoreCase) != -1) 
     { 
      DBTag = true; 
     } 

     if (HeroesDBFilterReleaseDateStart == null || HeroesDBFilterReleaseDateStart <= h.ReleaseDate) 
     { 
      ReleaseDateStart = true; 
     } 

     if (HeroesDBFilterReleaseDateEnd == null || HeroesDBFilterReleaseDateEnd >= h.ReleaseDate) 
     { 
      ReleaseDateEnd = true; 
     } 

     switch(HeroesDBFilterAvailable) 
     { 
      case 0: 
       Available = true; 
       break; 
      case 1: 
       if(h.Available == true) 
       { 
        Available = true; 
       } 
       break; 
      case 2: 
       if (h.Available == false) 
       { 
        Available = true; 
       } 
       break; 
     } 

     switch (HeroesDBFilterSale) 
     { 
      case 0: 
       Sale = true; 
       break; 
      case 1: 
       if (h.Sale == true) 
       { 
        Sale = true; 
       } 
       break; 
      case 2: 
       if (h.Sale == false) 
       { 
        Sale = true; 
       } 
       break; 
     } 

     switch (HeroesDBFilterFeatured) 
     { 
      case 0: 
       Featured = true; 
       break; 
      case 1: 
       if (h.Featured == true) 
       { 
        Featured = true; 
       } 
       break; 
      case 2: 
       if (h.Featured == false) 
       { 
        Featured = true; 
       } 
       break; 
     } 

     switch (HeroesDBFilterNew) 
     { 
      case 0: 
       New = true; 
       break; 
      case 1: 
       if (h.NewTag == true) 
       { 
        New = true; 
       } 
       break; 
      case 2: 
       if (h.NewTag == false) 
       { 
        New = true; 
       } 
       break; 
     } 

     switch (HeroesDBFilterF2P) 
     { 
      case 0: 
       F2P = true; 
       break; 
      case 1: 
       if (h.F2P == true) 
       { 
        F2P = true; 
       } 
       break; 
      case 2: 
       if (h.F2P == false) 
       { 
        F2P = true; 
       } 
       break; 
     } 

     switch (HeroesDBFilterHomepage) 
     { 
      case 0: 
       Homepage = true; 
       break; 
      case 1: 
       if (h.Homepage == true) 
       { 
        Homepage = true; 
       } 
       break; 
      case 2: 
       if (h.Homepage == false) 
       { 
        Homepage = true; 
       } 
       break; 
     } 

     switch (HeroesDBFilterThumbnail) 
     { 
      case 0: 
       Thumbnail = true; 
       break; 
      case 1: 
       if (h.ThumbnailImage.Count<byte>() >= 5) 
       { 
        Thumbnail = true; 
       } 
       break; 
      case 2: 
       if (h.ThumbnailImage.Count<byte>() < 5) 
       { 
        Thumbnail = true; 
       } 
       break; 
     } 

     switch (HeroesDBFilterFeaturedThumbnail) 
     { 
      case 0: 
       FeaturedThumbnail = true; 
       break; 
      case 1: 
       if (h.FeaturedThumbnailImage.Count<byte>() >= 5) 
       { 
        FeaturedThumbnail = true; 
       } 
       break; 
      case 2: 
       if (h.FeaturedThumbnailImage.Count<byte>() < 5) 
       { 
        FeaturedThumbnail = true; 
       } 
       break; 
     } 

     if (HeroesDBFilterShortDescription == "" || h.ShortDescription.IndexOf(HeroesDBFilterShortDescription, 0, StringComparison.CurrentCultureIgnoreCase) != -1) 
     { 
      ShortDescription = true; 
     } 

     if (HeroesDBFilterDescription == "" || h.Description.IndexOf(HeroesDBFilterDescription, 0, StringComparison.CurrentCultureIgnoreCase) != -1) 
     { 
      Description = true; 
     } 

     return ID && Name && GoldMinimum && GoldMaximum && PlatinumMinimum && PlatinumMaximum && DBTag && ReleaseDateStart && ReleaseDateEnd && Available && Sale && Featured && New && F2P && Homepage && Thumbnail && FeaturedThumbnail && ShortDescription && Description; 
    } 

我得到了下面的代碼片段以下錯誤:

An unhandled exception of type 'System.NotSupportedException' occurred in PresentationFramework.dll

Additional information: This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

private ICommand heroesDBAddEntry; 
public ICommand HeroesDBAddEntry 
{ 
    get 
    { 
     if (heroesDBAddEntry == null) 
     { 
      heroesDBAddEntry = new RelayCommand(HeroesDBAddEntryEx, null); 
     } 
     return heroesDBAddEntry; 
    } 
} 
private void HeroesDBAddEntryEx(object p) 
{ 
    if (HeroesDBUpdateID != null) 
    { 
     HeroesDBUpdateEntryEx(); 
     return; 
    } 

    int x; 
    var db = new SQLiteDatabase(); 

    string query, changesQuery; 

    query = "INSERT INTO Heroes (Name,Description,ShortDescription,Gold,Platinum,DBTag,ReleaseDate,Available,Sale,Featured,NewTag,F2P,Homepage,ThumbnailImage,ThumbnailImageName," + 
     "FeaturedThumbnailImage,FeaturedThumbnailImageName) "; 

    query += "VALUES ('" + HeroesDBName.Replace("'", "''") + "','" + HeroesDBDescription.Replace("'", "''") + "','" + HeroesDBShortDescription.Replace("'", "''") + "'," + 
     HeroesDBGold + "," + HeroesDBPlatinum + ",'" + HeroesDBDBTag.Replace("'", "''") + "','" + HeroesDBReleaseDate.Date.ToString("yyyy-MM-dd") + "'," + 
     Convert.ToInt32(HeroesDBAvailable) + "," + Convert.ToInt32(HeroesDBSale) + "," + Convert.ToInt32(HeroesDBFeatured) + "," + Convert.ToInt32(HeroesDBNewTag) + "," + 
     Convert.ToInt32(HeroesDBF2P) + "," + Convert.ToInt32(HeroesDBHomepage) + ",'" + Convert.ToBase64String(HeroesDBThumbnailImage) + "','" + 
     HeroesDBThumbnailPath.Replace("'", "''") + "','" + Convert.ToBase64String(HeroesDBFeaturedThumbnailImage) + "','" + HeroesDBFeaturedThumbnailPath.Replace("'", "''") + "'); "; 

    changesQuery = "INSERT INTO Heroes_Changes (HeroID,Action,TimeStamp,User,Name,Description,ShortDescription,Gold,Platinum,DBTag,ReleaseDate,Available,Sale,Featured,NewTag,F2P," + 
     "Homepage,ThumbnailImage,ThumbnailImageName,FeaturedThumbnailImage,FeaturedThumbnailImageName) "; 

    changesQuery += "VALUES (" + HeroesDBNextID + ",'" + "INSERT" + "','" + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") + "','" + Environment.UserName + "','" + 
     HeroesDBName.Replace("'", "''") + "','" + HeroesDBDescription.Replace("'", "''") + "','" + HeroesDBShortDescription.Replace("'", "''") + "'," + 
     HeroesDBGold + "," + HeroesDBPlatinum + ",'" + HeroesDBDBTag.Replace("'", "''") + "','" + HeroesDBReleaseDate.Date.ToString("yyyy-MM-dd") + "'," + 
     Convert.ToInt32(HeroesDBAvailable) + "," + Convert.ToInt32(HeroesDBSale) + "," + Convert.ToInt32(HeroesDBFeatured) + "," + Convert.ToInt32(HeroesDBNewTag) + "," + 
     Convert.ToInt32(HeroesDBF2P) + "," + Convert.ToInt32(HeroesDBHomepage) + ",'" + Convert.ToBase64String(HeroesDBThumbnailImage) + "','" + 
     HeroesDBThumbnailPath.Replace("'", "''") + "','" + Convert.ToBase64String(HeroesDBFeaturedThumbnailImage) + "','" + HeroesDBFeaturedThumbnailPath.Replace("'", "''") + "'); "; 

    try 
    { 
     x = db.ExecuteNonQuery(query); 
     HeroesDBStatus = x + " Record(s) Added."; 
     x = db.ExecuteNonQuery(changesQuery); 
    } 
    catch(Exception err) 
    { 
     System.Windows.Forms.MessageBox.Show(err.Message); 
    } 

    HeroesDBHeroes.Add(new Hero(
     HID: HeroesDBNextID, 
     HName: HeroesDBName, 
     HDescription: HeroesDBDescription, 
     HShortDescription: HeroesDBShortDescription, 
     HGold: HeroesDBGold, 
     HPlatinum: HeroesDBPlatinum, 
     HDBTag: HeroesDBDBTag, 
     HReleaseDate: HeroesDBReleaseDate, 
     HAvailable: HeroesDBAvailable, 
     HSale: HeroesDBSale, 
     HFeatured: HeroesDBFeatured, 
     HNewTag: HeroesDBNewTag, 
     HF2P: HeroesDBF2P, 
     HHomepage: HeroesDBHomepage, 
     HThumbnailImage: HeroesDBThumbnailImage, 
     HThumbnailImageName: HeroesDBThumbnailPath, 
     HFeaturedThumbnailImage: HeroesDBFeaturedThumbnailImage, 
     HFeaturedThumbnailImageName: HeroesDBFeaturedThumbnailPath, 
     HForce: true 
     )); 
    HeroesDBNextID++; 

    HeroesDBName = ""; 
    HeroesDBDescription = ""; 
    HeroesDBShortDescription = ""; 
    HeroesDBGold = 0; 
    HeroesDBPlatinum = 0; 
    HeroesDBDBTag = ""; 
    HeroesDBReleaseDate = DateTime.Today; 
    HeroesDBAvailable = false; 
    HeroesDBSale = false; 
    HeroesDBFeatured = false; 
    HeroesDBNewTag = false; 
    HeroesDBF2P = false; 
    HeroesDBHomepage = false; 
    HeroesDBThumbnailImage = new byte[] { 0x00 }; 
    HeroesDBThumbnailPath = ""; 
    HeroesDBFeaturedThumbnailImage = new byte[] { 0x00 }; 
    HeroesDBFeaturedThumbnailPath = ""; 
    HeroesDBUpdateID = null; 
} 

錯誤發生在我有HeroesDB.Add(...)行的地方,就在try catch之後。

我試了一大堆東西,其中沒有一個可以工作。

我已經嘗試使用另一個ObservableCollection作爲過濾列表和過濾,但它仍然給我一個錯誤。我曾嘗試使用從其他人發佈的谷歌第一頁獲取的MTObservableCollection和AsyncObservableCollection,但它們也以其他方式混淆。

我該如何去解決這個問題?我需要能夠過濾,我需要它們的集合,並且當源更改時,我需要立即在應用程序中查看這些更改。

+0

是你的HeroesDBAddEntry命令被非GUI線程調用嗎? – GazTheDestroyer

+0

被按下時按下按鈕。按鈕命令被綁定到它。 – pingu2k4

+0

我並不是故意表達衷心,但我建議你閱讀這本書。 http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882 –

回答

6

您是否嘗試過包裝所有設置過濾器的代碼以調用WPF調度程序?

通常,如果綁定到視圖的集合在不同於UI線程的線程的代碼中被修改,則必須完成此操作。

Application.Current.Dispatcher.BeginInvoke(
    DispatcherPriority.Background, 
    new Action(() => { 
    HeroesDBAddHeroes(); 
    })); 
+0

以多種方式嘗試了調度程序,但始終仍然出現錯誤。我將錯誤代碼放在調度程序中,錯誤如下:'PresentationFramework.dll中發生'System.NotSupportedException'類型的未處理的異常 其他信息:此類型的CollectionView不支持對其SourceCollection的更改,一個不同於Dispatcher線程的線程。' – pingu2k4

+0

奇怪。我確實記得,在設置「CollectionViewSource」的過濾器時,我曾經像你一樣出錯。將此代碼移到調度程序中爲我解決。 – Martin

+0

你的代碼中的哪一行會得到異常? – Martin

相關問題