绑定观察的词典列表框项目。 [WPF-C#] [英] Bind observable dictionary to listbox items. [WPF-C#]

查看:185
本文介绍了绑定观察的词典列表框项目。 [WPF-C#]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试绑定观察的词典列表框项目,我的问题是。如果我正常使用通用的字典,它的工作好。但是,如果使用可观察到的字典,列表框项目不会被加载。

下面是可观的字典类:

 公共类MyObservableDictionary< TKEY的,TValue> :
    IDictionary的< TKEY的,TValue>中
    INotifyCollectionChanged,
    INotifyPropertyChanged的
{
    私人只读IDictionary的< TKEY的,TValue> _dictionary =新词典< TKEY的,TValue>();    INotifyCollectionChanged的#区域实施    公共事件NotifyCollectionChangedEventHandler CollectionChanged;    #endregion    INotifyPropertyChanged的的#区域实施    公共事件PropertyChangedEventHandler的PropertyChanged;    #endregion    IEnumerable的的实施的#region    公众的IEnumerator< KeyValuePair< TKEY的,TValue>>的GetEnumerator()
    {
        返回_dictionary.GetEnumerator();
    }    的IEnumerator IEnumerable.GetEnumerator()
    {
        返回的GetEnumerator();
    }    #endregion    KeyValuePair< TKEY的,TValue>的ICollection&LT的#地区实施>    公共无效添加(KeyValuePair< TKEY的,TValue>的项目)
    {
        _dictionary.Add(项目);
        如果(CollectionChanged!= NULL)
            CollectionChanged(这一点,新NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
        如果(的PropertyChanged!= NULL)
        {
            的PropertyChanged(这一点,新PropertyChangedEventArgs(钥匙));
            的PropertyChanged(这一点,新PropertyChangedEventArgs(值));
        }    }    公共无效清除()
    {
        INT keysCount = _dictionary.Keys.Count;        _dictionary.Clear();        如果(keysCount == 0)回报;        如果(CollectionChanged!= NULL)
        {
            CollectionChanged(这一点,新NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }        如果(的PropertyChanged!= NULL)
        {
            的PropertyChanged(这一点,新PropertyChangedEventArgs(钥匙));
            的PropertyChanged(这一点,新PropertyChangedEventArgs(值));
        }
    }    公共BOOL包含(KeyValuePair< TKEY的,TValue>的项目)
    {
        返回_dictionary.Contains(项目);
    }    公共无效CopyTo从(KeyValuePair< TKEY的,TValue> []数组,诠释arrayIndex)
    {
        _dictionary.CopyTo(数组,arrayIndex);
    }    公共BOOL删除(KeyValuePair< TKEY的,TValue>的项目)
    {
        布尔删除= _dictionary.Remove(项目);        如果返回false(删除!);        如果(CollectionChanged!= NULL)
            CollectionChanged(这一点,新NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove));
        如果(的PropertyChanged!= NULL)
        {
            的PropertyChanged(这一点,新PropertyChangedEventArgs(钥匙));
            的PropertyChanged(这一点,新PropertyChangedEventArgs(值));
        }
        返回true;
    }    公众诠释计数
    {
        {返回_dictionary.Count; }
    }    公共BOOL IsReadOnly
    {
        {返回_dictionary.IsReadOnly; }
    }    #endregion    TKEY的,TValue>的IDictionary&LT的#区域执行情况;    公共BOOL的containsKey(TKEY的键)
    {
        返回_dictionary.ContainsKey(键);
    }    公共无效添加(TKEY的关键,TValue值)
    {
        _dictionary.Add(键,值);        如果(CollectionChanged!= NULL)
            CollectionChanged(这一点,新NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
        如果(的PropertyChanged!= NULL)
        {
            的PropertyChanged(这一点,新PropertyChangedEventArgs(钥匙));
            的PropertyChanged(这一点,新PropertyChangedEventArgs(值));
        }
    }    公共BOOL删除(TKEY的键)
    {
        布尔删除= _dictionary.Remove(键);        如果返回false(删除!);        如果(CollectionChanged!= NULL)
            CollectionChanged(这一点,新NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove));
        如果(的PropertyChanged!= NULL)
        {
            的PropertyChanged(这一点,新PropertyChangedEventArgs(钥匙));
            的PropertyChanged(这一点,新PropertyChangedEventArgs(值));
        }
        返回true;
    }    公共BOOL TryGetValue(TKEY的关键,走出TValue值)
    {
        返回_dictionary.TryGetValue(键,超时值);
    }    公共TValue这个[TKEY的关键]
    {
        {返回_dictionary [关键] }
        组
        {
            布尔改变= _dictionary [关键] .Equals(值);            如果(改!)回报;
            _dictionary [关键] =价值;            如果(CollectionChanged!= NULL)
                CollectionChanged(这一点,新NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace));            如果(的PropertyChanged!= NULL)
            {
                的PropertyChanged(这一点,新PropertyChangedEventArgs(钥匙));
                的PropertyChanged(这一点,新PropertyChangedEventArgs(值));
            }
        }
    }    公众的ICollection< TKEY的>按键
    {
        {返回_dictionary.Keys; }
    }    公众的ICollection< TValue>值
    {
        {返回_dictionary.Values​​; }
    }    #endregion
}

我在法,在那里我与反序列化JSON JSON.NET对象使用这个类。

朋友类:

 公共类FriendData
{
    公共字符串ID用户{搞定;组; }
    公共字符串尼克{搞定;组; }
    公共字符串sefNick {搞定;组; }
    公共字符串状态{搞定;组; }
    公共字符串照片{搞定;组; }
    公共字符串性爱{搞定;组; }
    公共字符串isFriend {搞定;组; }
    公众的BitmapImage profilePhoto {搞定;组; }
    公众的ImageSource的ImageSource {搞定;组; }
    公共字符串BLOCKQUOTE {搞定;组; }    公共FriendData(字符串ID用户,串缺口,串sefNick,串状态,串照片,串性别,串isFriend)
    {
        this.idUser = ID用户;
        this.nick =缺口;
        this.sefNick = sefNick;
        this.status =状态;
        this.photo =照片;
        this.sex =性;
        this.isFriend = isFriend;
    }
}公共MyObservableDictionary<字符串,FriendData> LoadFriendsData2(PokecAvatar pokecAvatar)
{
    //临时词典
    MyObservableDictionary<字符串,FriendData>朋友;    //字典,排序项
    VAR sortedFriends =新MyObservableDictionary<字符串,FriendData>();
    变种REQ =(HttpWebRequest的)WebRequest.Create(PokecUrl.Friends + pokecAvatar.SessionId +与& ALLDATA = 1);    req.Method =GET;    使用(WebResponse类odpoved = req.GetResponse())
    {
        使用(VAR SM =新的StreamReader(odpoved.GetResponseStream(),pokecAvatar.EncodingType))
        {
            字符串htmlString = sm.ReadToEnd();            尝试
            {
                VAR jsonString =新的StringBuilder();
                jsonString.Append(htmlString.Replace(@\\,​​).Replace(@S_,M_));                //使用JSON.NET,反序列化JSON字符串
                朋友= JsonConvert.DeserializeObject&所述; MyObservableDictionary&下;串,FriendData>>(jsonString.ToString());                的foreach(在朋友的朋友VAR)
                {
                    //获取引用
                    friend.Value.blockQuote = GetBlockQuote(friend.Value.nick);                    //没有照片
                    如果(friend.Value.photo ==0)
                    {
                        //人
                        如果(friend.Value.sex ==1)
                        {
                            //给默认的男人照片
                            VAR IMG =新的BitmapImage();
                            img.BeginInit();
                            img.UriSource =新的URI(@\\影像\\ ProfilePhoto \\ defaultPhotoMan.jpg,UriKind.RelativeOrAbsolute);
                            img.EndInit();
                            friend.Value.profilePhoto = IMG;
                            friend.Value.imageSource = IMG;
                        }
                        //女人
                        如果(friend.Value.sex ==2)
                        {
                            //给默认的女人照片
                            VAR IMG =新的BitmapImage();
                            img.BeginInit();
                            img.UriSource =新的URI(@\\影像\\ ProfilePhoto \\ defaultPhotoWoman.jpg,UriKind.RelativeOrAbsolute);
                            img.EndInit();
                            friend.Value.profilePhoto = IMG;
                            friend.Value.imageSource = IMG;
                        }
                    }
                    //有自己的照片
                    其他
                    {
                        VAR IMG =新的BitmapImage();
                        img.BeginInit();
                        img.UriSource =新的URI(friend.Value.photo,UriKind.Absolute);
                        img.EndInit();
                        friend.Value.profilePhoto = IMG;
                        friend.Value.imageSource = IMG;
                    }                }                在dictoniary //排序项
                VAR的查询= friends.OrderByDescending(F => f.Value.status).ThenBy(F => f.Value.nick);                的foreach(查询VAR keyValuePair)
                {
                    sortedFriends.Add(keyValuePair.Key,keyValuePair.Value);
                }
            }
            赶上(异常前)
            {
                扔恩;
            }
        }
    }
    返回sortedFriends;
}

和我使用的方法LoadFriendsData2的结果在我的WPF应用程序。

 私人MyObservableDictionary<字符串,FriendData> _friendsData;    // ...    私人无效Window_Loaded(对象发件人,RoutedEventArgs E)
    {
        _pokecCmd =新PokecCommands();

/ * !!!!!
问题就在这里,_friendsData是空的,如果我使用普通通用词典一切正常* /
            _friendsData = _pokecCmd.LoadFriendsData2(PokecAvatar);

  friendsListBox.DataContext = _friendsData;
    }

XAML是在这里:

 <列表框名称=friendsListBox
             的ItemsSource ={结合}
             的SelectedItem =密钥
             风格={DynamicResource friendsListStyle}
             previewMouseRightButtonUp =ListBox_ previewMouseRightButtonUp
             previewMouseRightButtonDown =ListBox_ previewMouseRightButtonDown
             Grid.Row =1的MouseRightButtonDown =friendsListBox_MouseRightButtonDown>
            < ListBox.ItemContainerStyle>
            <风格的TargetType ={X:输入一个ListBoxItem}>
                < EventSetter事件=MouseDoubleClick处理器=ListBoxItem_MouseDoubleClick/>
            < /样式和GT;
            < /ListBox.ItemContainerStyle>
            < ListBox.ContextMenu>
                 <文本菜单X:NAME =FriendContextMenu>
                <菜单项名称=SendRp标题=PošliRP点击=FriendContextMenuItem_Click/>
                <菜单项名称=SENDMSG标题=Pošlipoštu点击=FriendContextMenuItem_Click/>
            < /文本菜单>
            < /ListBox.ContextMenu>
        < /列表框>

任何进展?我不知道什么可以是错误的,JSON.NET。
也许是这里的问题。

  =朋友与JsonConvert.DeserializeObject LT; MyObservableDictionary<字符串,FriendData>>(jsonString.ToString());


解决方案

请问朋友变量(和它包含的项目)有一个非空使用后

  =朋友与JsonConvert.DeserializeObject LT; MyObservableDictionary<字符串,FriendData>>(jsonString.ToString());


根据JSON.NET的实施,它可能是朋友序列化为一个对象,以便它包含的属性,如计数 IsReadOnly 等,而不是像字典。
进一步阅读,请参见这里

I try bind observable dictionary to listbox item, and my problem is. If I use normal generic dictionary, it works good. But if I use observable dictionary, listbox items are not loaded.

Here is observable dictionary class:

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
}

I use this class in my method, where I deserialize JSON object with JSON.NET.

Friend class:

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

And I use result of method LoadFriendsData2 in my WPF app.

    private MyObservableDictionary<string, FriendData> _friendsData;

    //...

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

/*!!!!! problem is here, _friendsData are null, if i use normal generic dictionary everything is OK*/ _friendsData = _pokecCmd.LoadFriendsData2(PokecAvatar);

        friendsListBox.DataContext = _friendsData;
    }

XAML is here:

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

Any advance? I dont know what can be wrong, JSON.NET. Maybe is problem here.

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

解决方案

Does the friends variable (and the items contained in it) have a non-null after using

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

? Depending on the implementation of JSON.NET, it might be that friends is serialized as an object, so that it contains properties like Count IsReadOnly etc, and not like a Dictionary. for further reading, see here

这篇关于绑定观察的词典列表框项目。 [WPF-C#]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆