3

I'm trying to do something very simple : I want to display an ObservableCollection in an ItemsControl. I also want the user to be able to edit the strings in the ObservableCollection.

My viewmodel is pretty straightforward :

public class MainViewModel : ViewModelBase
{
    public ObservableCollection<string> Values { get; set; }

    public MainViewModel()
    {
        Values = new ObservableCollection<string> { "foo", "bar" };
    }
}

In my view, I define a DataTemplate for my ItemsControl to display a textbox inside each item, no problem here :

<ItemsControl ItemsSource="{Binding Values}">
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type sys:String}">
                    <TextBox Text="{Binding Path=., UpdateSourceTrigger=PropertyChanged}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

Everything seems to work smoothly, I can see the content of my ObservableCollection in my view. However, when I edit the text in the textbox, my ObservableCollection is not updated, the values are still the same.

The only workaround I've found to make this work is to create a class :

public class StringWrapper
{
    public string Value { get; set; }
}

Then I change the type of my ObservableCollection to ObservableCollection<StringWrapper>, and in my DataTemplate, I bind the Text property of my TextBox to Value. It works, but it's ugly.

So my question is, is there a way to bind an ObservableCollection to an ItemsControl and be able to update the values ?

MisterBait
  • 41
  • 2
  • 6

3 Answers3

3

Except if it's handled directly by the list control, I doubt there's any way to do that. The templated item in your ItemsControl only have access to the string instance, not to the actual collection. And since string is immutable, it's a dead end, there is no way to trace back the changes to the parent.

Kevin Gosse
  • 38,392
  • 3
  • 78
  • 94
  • I didn't know `string` was immutable in C#. Now I understand better why it's a good pratice to use `StringBuilder`instead of directly modifying a `string`. I'll stick to the ugly way then, thanks! – MisterBait May 28 '15 at 13:05
1

your property Values need to be implement INotifyPropertyChanged interface, after only binding with Values property will work.

0

I think Binding to itself will do the work + dont forget to put it twoway.

TextBox Text="{Binding}",Mode=TwoWay

Ben Cohen
  • 1,380
  • 1
  • 9
  • 12