I have a DataGrid bound to the People collection. Also I have a TextBox that should accept the Name value from the selected row. User can then edit the value or can leave it as is. The key point is: the text shown in the TextBox no matter whether it originates from collection or user typing must be propagated to the property NewName.
I've set two bindings for the NewNameTextBox: OneWay'ed to the CollectionView behind the DataGrid, and OneWayToSource'ed to the property:
<Window.Resources>
<CollectionViewSource x:Key="PeopleCollection"
Source="{Binding Path=People, Mode=OneWay}" />
<local:ConverterNewNamePrefill x:Key="ConverterNewNamePrefill" />
</Window.Resources>
<Grid>
<StackPanel>
<DataGrid ItemsSource="{Binding Source={StaticResource PeopleCollection}}"
AutoGenerateColumns="True"
IsReadOnly="True"
Margin="10">
</DataGrid>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBox>
<TextBox.Text>
<MultiBinding Converter="{StaticResource ConverterNewNamePrefill}" >
<Binding Source="{StaticResource PeopleCollection}" Path="Name" Mode="OneWay" />
<Binding Path="NewName" Mode="OneWayToSource" />
</MultiBinding>
</TextBox.Text>
</TextBox>
</StackPanel>
</StackPanel>
</Grid>
I suppose the property should be updated when user changes selection in the DataGrid, but this doesn't happen. The TextBox gets updated and shows the selected Name value, but the property bound via OneWayToSource remains unchanged.
If the user types into the TextBox, the property gets updated as expected.
So the question is how can I update a property from both the sources via multi-bound TextBox without code behind view?
Here is the code behind window:
public class Person
{
public string Name { get; set; }
public string Surname { get; set; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private ObservableCollection<Person> _people = new ObservableCollection<Person> {
new Person() {Name = "Mitchell", Surname = "Sofia" },
new Person() {Name="Bush", Surname="Ethan" },
new Person() {Name="Ferrero", Surname="Emma" },
new Person() {Name="Thompson", Surname="Aiden" }
};
public ObservableCollection<Person> People => _people;
public string NewName { get; set; } = "Jackson";
}
public class ConverterNewNamePrefill : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[0];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new[] { value, value };
}
}
The converter's method ConvertBack() is called only when user types, but not when the TextBox.Text updated from collection.
Thank you!