2010-11-05 91 views
2

我嘗試將可觀察字典綁定到列表框項目,我的問題是。如果我使用普通的通用字典,它的效果很好。但是,如果我使用可觀察字典,則不會加載列表框項目。將可觀察字典綁定到列表框項目。 [WPF-C#]

這裏是觀測的字典類:

public class MyObservableDictionary<TKey, TValue> : 
    IDictionary<TKey, TValue>, 
    INotifyCollectionChanged, 
    INotifyPropertyChanged 
{ 
    private readonly IDictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>(); 

    #region Implementation of INotifyCollectionChanged 

    public event NotifyCollectionChangedEventHandler CollectionChanged; 

    #endregion 

    #region Implementation of INotifyPropertyChanged 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 

    #region Implementation of IEnumerable 

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() 
    { 
     return _dictionary.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    #endregion 

    #region Implementation of ICollection<KeyValuePair<TKey,TValue>> 

    public void Add(KeyValuePair<TKey, TValue> item) 
    { 
     _dictionary.Add(item); 
     if (CollectionChanged != null) 
      CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add)); 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("Keys")); 
      PropertyChanged(this, new PropertyChangedEventArgs("Values")); 
     } 

    } 

    public void Clear() 
    { 
     int keysCount = _dictionary.Keys.Count; 

     _dictionary.Clear(); 

     if (keysCount == 0) return; 

     if (CollectionChanged != null) 
     { 
      CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
     } 

     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("Keys")); 
      PropertyChanged(this, new PropertyChangedEventArgs("Values")); 
     } 
    } 

    public bool Contains(KeyValuePair<TKey, TValue> item) 
    { 
     return _dictionary.Contains(item); 
    } 

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) 
    { 
     _dictionary.CopyTo(array, arrayIndex); 
    } 

    public bool Remove(KeyValuePair<TKey, TValue> item) 
    { 
     bool remove = _dictionary.Remove(item); 

     if (!remove) return false; 

     if (CollectionChanged != null) 
      CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove)); 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("Keys")); 
      PropertyChanged(this, new PropertyChangedEventArgs("Value")); 
     } 
     return true; 
    } 

    public int Count 
    { 
     get { return _dictionary.Count; } 
    } 

    public bool IsReadOnly 
    { 
     get { return _dictionary.IsReadOnly; } 
    } 

    #endregion 

    #region Implementation of IDictionary<TKey,TValue> 

    public bool ContainsKey(TKey key) 
    { 
     return _dictionary.ContainsKey(key); 
    } 

    public void Add(TKey key, TValue value) 
    { 
     _dictionary.Add(key, value); 

     if (CollectionChanged != null) 
      CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add)); 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("Keys")); 
      PropertyChanged(this, new PropertyChangedEventArgs("Values")); 
     } 
    } 

    public bool Remove(TKey key) 
    { 
     bool remove = _dictionary.Remove(key); 

     if (!remove) return false; 

     if (CollectionChanged != null) 
      CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove)); 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("Keys")); 
      PropertyChanged(this, new PropertyChangedEventArgs("Values")); 
     } 
     return true; 
    } 

    public bool TryGetValue(TKey key, out TValue value) 
    { 
     return _dictionary.TryGetValue(key, out value); 
    } 

    public TValue this[TKey key] 
    { 
     get { return _dictionary[key]; } 
     set 
     { 
      bool changed = _dictionary[key].Equals(value); 

      if (!changed) return; 
      _dictionary[key] = value; 

      if (CollectionChanged != null) 
       CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace)); 

      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("Keys")); 
       PropertyChanged(this, new PropertyChangedEventArgs("Values")); 
      } 
     } 
    } 

    public ICollection<TKey> Keys 
    { 
     get { return _dictionary.Keys; } 
    } 

    public ICollection<TValue> Values 
    { 
     get { return _dictionary.Values; } 
    } 

    #endregion 
} 

我我的方法,我在那裏與反序列化JSON JSON.NET對象使用這個類。

朋友類:

public class FriendData 
{ 
    public string idUser { get; set; } 
    public string nick { get; set; } 
    public string sefNick { get; set; } 
    public string status { get; set; } 
    public string photo { get; set; } 
    public string sex { get; set; } 
    public string isFriend { get; set; } 
    public BitmapImage profilePhoto { get; set; } 
    public ImageSource imageSource { get; set; } 
    public string blockQuote { get; set; } 

    public FriendData(string idUser, string nick, string sefNick, string status, string photo, string sex, string isFriend) 
    { 
     this.idUser = idUser; 
     this.nick = nick; 
     this.sefNick = sefNick; 
     this.status = status; 
     this.photo = photo; 
     this.sex = sex; 
     this.isFriend = isFriend; 
    } 
} 

public MyObservableDictionary<string, FriendData> LoadFriendsData2(PokecAvatar pokecAvatar) 
{ 
    //temp dictionary 
    MyObservableDictionary<string, FriendData> friends; 

    //dictionary with sorted item 
    var sortedFriends = new MyObservableDictionary<string, FriendData>(); 


    var req = (HttpWebRequest)WebRequest.Create(PokecUrl.Friends + pokecAvatar.SessionId + "&allData=1"); 

    req.Method = "GET"; 

    using (WebResponse odpoved = req.GetResponse()) 
    { 
     using (var sm = new StreamReader(odpoved.GetResponseStream(), pokecAvatar.EncodingType)) 
     { 
      string htmlString = sm.ReadToEnd(); 

      try 
      { 
       var jsonString = new StringBuilder(); 
       jsonString.Append(htmlString.Replace(@"\", "").Replace(@"s_", "m_")); 

       //using JSON.NET, deserialize JSON string 
       friends = JsonConvert.DeserializeObject<MyObservableDictionary<string, FriendData>>(jsonString.ToString()); 

       foreach (var friend in friends) 
       { 
        //get citation 
        friend.Value.blockQuote = GetBlockQuote(friend.Value.nick); 

        //don’t have a foto 
        if (friend.Value.photo == "0") 
        { 
         //man 
         if (friend.Value.sex == "1") 
         { 
          //give default man photo 
          var img = new BitmapImage(); 
          img.BeginInit(); 
          img.UriSource = new Uri(@"\Images\ProfilePhoto\defaultPhotoMan.jpg", UriKind.RelativeOrAbsolute); 
          img.EndInit(); 
          friend.Value.profilePhoto = img; 
          friend.Value.imageSource = img; 
         } 
         //woman 
         if (friend.Value.sex == "2") 
         { 
          //give default woman photo 
          var img = new BitmapImage(); 
          img.BeginInit(); 
          img.UriSource = new Uri(@"\Images\ProfilePhoto\defaultPhotoWoman.jpg", UriKind.RelativeOrAbsolute); 
          img.EndInit(); 
          friend.Value.profilePhoto = img; 
          friend.Value.imageSource = img; 
         } 
        } 
        //have own photo 
        else 
        { 
         var img = new BitmapImage(); 
         img.BeginInit(); 
         img.UriSource = new Uri(friend.Value.photo, UriKind.Absolute); 
         img.EndInit(); 
         friend.Value.profilePhoto = img; 
         friend.Value.imageSource = img; 
        } 

       } 

       //sort item in dictoniary 
       var query = friends.OrderByDescending(f => f.Value.status).ThenBy(f => f.Value.nick); 

       foreach (var keyValuePair in query) 
       { 
        sortedFriends.Add(keyValuePair.Key, keyValuePair.Value); 
       } 
      } 
      catch (Exception ex) 
      { 
       throw ex; 
      } 
     } 
    } 
    return sortedFriends; 
} 

而且我用的方法LoadFriendsData2的結果在我的WPF應用程序。

private MyObservableDictionary<string, FriendData> _friendsData; 

    //... 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     _pokecCmd = new PokecCommands(); 

/* !!!!! 問題在這裏,_friendsData爲空,如果我使用正常的通用字典,一切正常*/ _friendsData = _pokecCmd.LoadFriendsData2(PokecAvatar);

 friendsListBox.DataContext = _friendsData; 
    } 

XAML是在這裏:

<ListBox Name="friendsListBox" 
      ItemsSource="{Binding}" 
      SelectedItem="Key" 
      Style="{DynamicResource friendsListStyle}" 
      PreviewMouseRightButtonUp="ListBox_PreviewMouseRightButtonUp" 
      PreviewMouseRightButtonDown="ListBox_PreviewMouseRightButtonDown" 
      Grid.Row="1" MouseRightButtonDown="friendsListBox_MouseRightButtonDown"> 
      <ListBox.ItemContainerStyle> 
      <Style TargetType="{x:Type ListBoxItem}"> 
       <EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/> 
      </Style> 
      </ListBox.ItemContainerStyle> 
      <ListBox.ContextMenu> 
       <ContextMenu x:Name="FriendContextMenu"> 
       <MenuItem Name="SendRp" Header="Pošli Rp" Click="FriendContextMenuItem_Click" /> 
       <MenuItem Name="SendMsg" Header="Pošli poštu" Click="FriendContextMenuItem_Click"/> 
      </ContextMenu> 
      </ListBox.ContextMenu> 
     </ListBox> 

任何進展?我不知道什麼是錯的,JSON.NET。 也許這裏是問題。

friends = JsonConvert.DeserializeObject<MyObservableDictionary<string, FriendData>>(jsonString.ToString()); 

回答

0

如果您更改綁定到

ItemsSource="{Binding Path=Keys}" 
+0

我相同,它不起作用。 ( – Joe 2010-11-05 19:23:58

1

什麼是friends變量(和它包含的項目)都使用

friends = JsonConvert.DeserializeObject<MyObservableDictionary<string, FriendData>>(jsonString.ToString()); 

後一個非空? 根據JSON.NET的實現情況,可能將friends作爲對象序列化,以便它包含諸如CountIsReadOnly等的屬性,而不像字典。 進一步閱讀,請參閱here