Question

recently i ran into a problem (might be important to mention: i am creating an Metro App):

i created a databinding between an ObservableDictionary (or a Dictionary, or an ObservableCollection<KeyValuePair<string,string>>) and a GridView. Each GridView item contains two Textblocks bound to Key and Value of each Pair of the Dictonary. However, there are exactly as many Textblocks as items inside the dictionary, but these boxes do not contain any text.

Strange thing: when not binding by Text={Binding Key} or Text={Binding Value} but using Text={Binding} the text is displayed as one would expect it ([someKey,someValue]).

Some code (reduced to the essentials):

private ObservableDictionary _someDictionary=new ObservableDictionary();
public ObservableDictionary SomeDictionary { 
    get { return _someDictionary; }
    set { _someDictionary = value; } 
}

public SomePage() {
    this.InitializeComponent();            
    SomeDictionary.Add("TestKey", "TestValue");
    SomeDictionary.Add("TestKey2", "TestValue2");
    SomeDictionary.Add("TestKey3", "TestValue3");
}

WPF:

<Page
x:Class="TestView.Settings"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <GridView ItemsSource="{Binding Path=SomeDictionary}">
            <GridView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Name="Key" Text="{Binding Path=Key}" />
                        <TextBlock Name="Value" Text="{Binding Path=Value}" />
                    </StackPanel>
                </DataTemplate>
            </GridView.ItemTemplate>
        </GridView>
    </Grid>
</Page>

Does anyone have an idea, what is wrong here?

Thanks in advance :)

Was it helpful?

Solution

For not heaving headaches for a too long time i decided to write my own little generic class extending ObservableCollection containing some Key-Value-Elements. It's by far enough for small needs. It's properties are bindable by using {Binding Path=Key} and {Path=Value}.

Maybe this will be useful for somebody else:

using System.Collections.ObjectModel;

namespace MyNamespace{
    public class BindableValuePairList<TK,TV> : 
        ObservableCollection<ValuePair<TK,TV>> { }

    public class ValuePair<TK,TV> {
        public ValuePair (TK key, TV value) {
            Key = key;
            Value= value;
        }

        public TK Key { get; set; }

        public TV Value { get; set; }
    }
}

OTHER TIPS

nYou just have to remove the path from the Binding in the DataTemplate

<TextBlock Name="Key" Text="{Binding Key}" />
<TextBlock Name="Value" Text="{Binding Value}" />

With Path=Key you bind the content of the text box to a object with the name Key not the Key in the Collection.

And you also have to bind the StackPanel to the KeyValuePair of the dictionary, because the enummerator of a Dictionary returns a KeyValuePair.

It would look like this:

<StackPanel Orientation="Horizontal" DataContext={Binding}>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top