I have a list view that displays the EditCollection property stored in a viewmodel which is of type ObservableCollection. It displays each element as a textbox with the string as its text so I can edit the string of each element. There is an Add button that adds an element whose handler is AddToCollection. There is also a Save button. When it is clicked, EditCollection should be copied into another ObservableCollection property called Collection. But what actually happens is that any added elements are shown, but their edited values do not appear in EditCollection, only their default values.
private ObservableCollection<string> _editCollection;
public ObservableCollection<string> EditCollection
{
get { return _editCollection; }
set
{
_editCollection = value;
OnPropertyChanged("EditCollection");
}
}
private ObservableCollection<string> _collection;
public ObservableCollection<string> Collection
{
get { return _collection; }
set
{
_collection = value;
_editCollection = new ObservableCollection<string>(_collection);
OnPropertyChanged("Collection");
OnPropertyChanged("EditCollection");
}
}
public void Save(object item)
{
string value;
if (EditCollection.Count > 1)
{
value = EditCollection[1];
}
; // break point: value = "default value" even if I edit the textbox
Collection = new ObservableCollection<string>(new List<string>( EditCollection ));
}
public void AddToCollection(object item)
{
EditCollection.Add("default value");
OnPropertyChanged("EditCollection");
}
view.xaml
<Button Content="Save" Width="50" HorizontalAlignment="Right"
Command="{Binding SaveCommand}"/>
<ListView Grid.Row="1" ItemsSource="{Binding Path=EditCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding Path=.,
UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Grid.Row="2" Content="Add" Width="50" HorizontalAlignment="Center"
Command="{Binding AddToCollectionCommand}"/>
CodePudding user response:
The way to do this is bind to a class instead of the string directly.
private ObservableCollection<Item> _editCollection;
public ObservableCollection<Item> EditCollection
{
get { return _editCollection; }
set
{
_editCollection = value;
OnPropertyChanged("EditCollection");
}
}
public class Item
{
public string Text {get;set;}
}
<ListView Grid.Row="1" ItemsSource="{Binding Path=EditCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding Path=Text,
UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>