2010-11-05 17 views
2

J'essaie de lier le dictionnaire observable à l'élément de la liste, et mon problème est. Si j'utilise un dictionnaire générique normal, cela fonctionne bien. Mais si j'utilise un dictionnaire observable, les éléments de la liste ne sont pas chargés.Liez le dictionnaire observable aux éléments de la liste. [WPF-C#]

Voici observable classe dictionnaire:

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 
} 

J'utilise cette classe dans ma méthode, où je deserialize objet JSON avec JSON.NET.

classe ami:

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; 
} 

Et j'utilise résultat de la méthode LoadFriendsData2 dans mon application WPF.

private MyObservableDictionary<string, FriendData> _friendsData; 

    //... 

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

/* !!!!! problème est ici, _friendsData sont null, si j'utilise le dictionnaire générique normal tout est OK */ _friendsData = _pokecCmd.LoadFriendsData2 (PokecAvatar);

 friendsListBox.DataContext = _friendsData; 
    } 

XAML est ici:

<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> 

Toute avance? Je ne sais pas ce qui ne va pas, JSON.NET. Peut-être que c'est un problème ici.

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

Répondre

0

si vous changez la liaison à

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

Je même, cela ne fonctionne pas. ( – Joe

1

Est-ce que la variable friends (et les éléments qu'il contient) ont un non nul après avoir utilisé

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

? En fonction de l'implémentation de JSON.NET, il se peut que friends soit sérialisé en tant qu'objet, de sorte qu'il contienne des propriétés telles que CountIsReadOnly etc, et non comme un dictionnaire. pour plus de lecture, voir here