2

I currently have an application where I'm parsing a YAML dictionary. I have a model named Line that looks like this -

    public class Line
    {

        private ObservableDictionary<string, string> language = new ObservableDictionary<string, string>();

        public Line()
        {
            Language = new Dictionary<string, string>();
        }

        // used with the YAML parser
        [YamlMember(Alias = "language")]
        public Dictionary<string, string> Language { get; set; }

    }

You've probably noticed that I'm using an ObservableDictionary, which is not a standard type. I took the code from this other StackOverflow answer. As I understand it, it's just setting up the necessary INotifyPropertyChanged interface.

Anyway, for my Line, I have a ListView populated with a dictionary of translations represented as the language abbreviation and a textbox. To better exemplify what I'm talking about, here is a graphic.

enter image description here

In my App.xaml, I have a DataTemplate for my ListView defined - together, they look like this:

<ListView 
    ItemTemplate="{StaticResource LinesTemplateItem}" 
    ItemsSource="{Binding Value.Language}" 
    SelectionMode="None">
</ListView>

...

<DataTemplate x:Key="LinesTemplateItem">
    <StackPanel Background="Transparent">
        <TextBlock Text="{Binding Key}" />
        <TextBox Text="{Binding Value, Mode=TwoWay}" />
    </StackPanel>
</DataTemplate>

Everything seems like it should work fine. My data shows properly. However, when I change a value, it does not update the underlying source with the error:

Error: Cannot save value from target back to source. 
BindingExpression: Path='Value' DataItem='Windows.Foundation.Collections.IKeyValuePair`2<String,String>'; 
target element is 'Windows.UI.Xaml.Controls.TextBox' (Name='null'); 
target property is 'Text' (type 'String').

From the error, I would guess that for some reason the databinding is targeting the entire UI control instead of the text inside of it. I've been searching for a while, but I can't seem to figure out how to fix this error. Any help is appreciated. Thanks.

Community
  • 1
  • 1
Alexander Lozada
  • 4,019
  • 3
  • 19
  • 41

2 Answers2

2

The problem is that the property IKeyValuePair.Value is read-only so you cannot modify it. My proposition is to change you data model a little bit i.e. firstly create an additional class to store translations.

public class Translation
{
   public string Expression { get; set; }
}

Now you should also change a definition of your dictionary e.g.:

public Dictionary<string, Translation> Language { get; set; }

Binding should be also updated accordingly:

<TextBox Text="{Binding Value.Expression, Mode=TwoWay}" />

Thanks to that if you change a value, the data binding will update Expression property which is not read-only.

I didn't test this code but I did similar things in the past so something like that should work.

Michał Komorowski
  • 6,198
  • 1
  • 20
  • 24
1

Since you're binding to Dictionary<string,string>, each item is bound to KeyValuePair<string,string>, which is of value type - it's fields cannot be changed (while unboxed). You should bind to the pair itself, rather than its parts and use value converter to produce a pair with changed value.

stop-cran
  • 4,229
  • 2
  • 30
  • 47