在Windows Phone中绑定ObservableDictionary时遇到问题

时间:2013-12-18 13:43:46

标签: c# xaml windows-phone-8

我从VS2013生成的项目中复制了这个ObservableDictionary实现。它是一个强类型实现(Key是字符串,Value是对象)。但是,我必须得到绑定错误,因为我没有看到任何数据,我得到一个BindingExpression路径错误。 我注意到的一件事是MapChangedEventHandler总是为null,这意味着每个人都注册了这个事件! 1.谁或什么注册MapChangedEventHandler? 2.我的绑定应该是什么?我已经尝试了几种不同的绑定排列。一切都无济于事,但这是代码的最新排列:

    public class ObservableDictionary : IObservableMap<string, object>
{
    private class ObservableDictionaryChangedEventArgs : IMapChangedEventArgs<string>
    {
        public ObservableDictionaryChangedEventArgs(CollectionChange change, string key)
        {
            this.CollectionChange = change;
            this.Key = key;
        }

        public CollectionChange CollectionChange { get; private set; }
        public string Key { get; private set; }
    }

    private Dictionary<string, object> _dictionary = new Dictionary<string, object>();
    public event MapChangedEventHandler<string, object> MapChanged;

    private void InvokeMapChanged(CollectionChange change, string key)
    {
        var eventHandler = MapChanged;
        if (eventHandler != null)
        {
            eventHandler(this, new ObservableDictionaryChangedEventArgs(change, key));
        }
    }

    public void Add(string key, object value)
    {
        this._dictionary.Add(key, value);
        this.InvokeMapChanged(CollectionChange.ItemInserted, key);
    }

    public void Add(KeyValuePair<string, object> item)
    {
        this.Add(item.Key, item.Value);
    }

    public bool Remove(string key)
    {
        if (this._dictionary.Remove(key))
        {
            this.InvokeMapChanged(CollectionChange.ItemRemoved, key);
            return true;
        }
        return false;
    }

    public bool Remove(KeyValuePair<string, object> item)
    {
        object currentValue;
        if (this._dictionary.TryGetValue(item.Key, out currentValue) &&
            Object.Equals(item.Value, currentValue) && this._dictionary.Remove(item.Key))
        {
            this.InvokeMapChanged(CollectionChange.ItemRemoved, item.Key);
            return true;
        }
        return false;
    }

    public object this[string key]
    {
        get
        {
            return this._dictionary[key];
        }
        set
        {
            this._dictionary[key] = value;
            this.InvokeMapChanged(CollectionChange.ItemChanged, key);
        }
    }

    public void Clear()
    {
        var priorKeys = this._dictionary.Keys.ToArray();
        this._dictionary.Clear();
        foreach (var key in priorKeys)
        {
            this.InvokeMapChanged(CollectionChange.ItemRemoved, key);
        }
    }

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

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

    public bool TryGetValue(string key, out object value)
    {
        return this._dictionary.TryGetValue(key, out value);
    }

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

    public bool Contains(KeyValuePair<string, object> item)
    {
        return this._dictionary.Contains(item);
    }

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

    public bool IsReadOnly
    {
        get { return false; }
    }

    public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
    {
        return this._dictionary.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this._dictionary.GetEnumerator();
    }

    public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
    {
        int arraySize = array.Length;
        foreach (var pair in this._dictionary)
        {
            if (arrayIndex >= arraySize) break;
            array[arrayIndex++] = pair;
        }
    }
}

和xaml:

<custom:RESTAPHandler
x:Class="K1MobilePhone.Views.HomePageAdmin"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:custom="clr-namespace:K1MobilePhone.Utilities"
xmlns:cells="clr-namespace:K1MobilePhone.Common"
xmlns:wptoolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True" Loaded="phoneApplicationPage_Loaded" Margin="0,6,0,-6">
<custom:RESTAPHandler.Resources>
    <CollectionViewSource
        x:Name="sd_source" Source="{Binding Path=SDSummaries, Mode=TwoWay}" />
    <CollectionViewSource
        x:Name="ticketsViewSource" Source="{Binding Path=Tickets, Mode=TwoWay}" />
</custom:RESTAPHandler.Resources>

现在是xaml.cs:

   public sealed partial class HomePageAdmin : RESTAPHandler
{
    private ObservableDictionary defaultViewModel = new ObservableDictionary();
    public ObservableDictionary DefaultViewModel { get { return this.defaultViewModel; } }

    public HomePageAdmin() : base()
    {
        this.InitializeComponent();
        DataContext = this.DefaultViewModel;
        this.DefaultViewModel["SDSummaries"] = new SDSummaries();
        this.DefaultViewModel["Tickets"] = new RecentlyViewedTickets();
    }

1 个答案:

答案 0 :(得分:0)

好吧,我无法弄清楚为什么我无法在xaml代码中访问基于字符串的键。默认的Windows应用商店应用效果很好。我最后做的是:

Page.xaml:

   <custom:RESTAPHandler.Resources>
    <CollectionViewSource
        x:Name="sd_source"/>
    <CollectionViewSource
        x:Name="ticketsViewSource"/>
</custom:RESTAPHandler.Resources>

我在代码隐藏中构建了所有内容:

    public sealed partial class HomePageAdmin : RESTAPHandler
{
    private Grid visibleGrid;
    private SDSummaries _sdSummaries = new SDSummaries();
    public SDSummaries SDSummaries { get { return this._sdSummaries; } }

    public HomePageAdmin() : base()
    {
        this.InitializeComponent();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        this.sd_source.Source = this.SDSummaries;
        base.OnNavigatedTo(e);
    }


    private void phoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
    {
        this.Address = this.NavigationContext.QueryString["URL"];
    }

    private void TicketsStatsResponse (TicketsStatsResponse response)
    {
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            PlainTitleDisclosureCellItem cell = (PlainTitleDisclosureCellItem)this.SDSummaries[1];
            cell.Label = response.NewTicketCount.ToString();
            cell = (PlainTitleDisclosureCellItem)this.SDSummaries[2];
            cell.Label = response.UnassignedTicketCount.ToString();
        });
    }

似乎有点黑客,但我不确定。