我尝试将可观察字典绑定到列表框项目,我的问题是。如果我使用普通的通用字典,它的效果很好。但是如果我使用可观察的字典,则不会加载列表框项。
这是可观察的字典类:
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.NET反序列化JSON对象。
朋友班:
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;
}
我在我的WPF应用程序中使用方法LoadFriendsData2的结果。
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 :(得分:2)
friends
变量(及其中包含的项)在使用后是否为非空
friends = JsonConvert.DeserializeObject<MyObservableDictionary<string, FriendData>>(jsonString.ToString());
?
根据JSON.NET的实现,可能会将friends
序列化为对象,因此它包含Count
IsReadOnly
等属性,而不是像Dictionary。
如需进一步阅读,请参阅here
答案 1 :(得分:0)
如果您将绑定更改为
,该怎么办?ItemsSource="{Binding Path=Keys}"