2010-11-05 3 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 имеют значение null, если я использую обычный общий словарь, все в порядке */ _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

1

ли friends переменной (и элементы, содержащиеся в нем) имеют непустое после использования

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

? В зависимости от реализации JSON.NET может быть, что friends сериализуется как объект, так что он содержит такие свойства, как CountIsReadOnly и т. Д., А не как словарь. для дальнейшего ознакомления, см. here

Смежные вопросы