Reputation: 13645
I am new to WPF and bindings and I wanted to see if there is a way to do a two way binding between an array element and a control:
My ViewModel has a property which looks like following:
public ObservableCollection<MeaseurementValue> MeasurementValues
{
get
{
return Config.MeasurementValues;
}
set
{
if (value == null) return;
Config.MeasurementValues = value;
OnPropertyChanged("MeasurementValues");
QpatConfig.SerializeConfigFile(Config,
Path.GetPathRoot(Environment.GetFolderPath(Environment.SpecialFolder.System)) + "//Qualcomm//QPAT//qpat.config");
}
}
Where MeasurementValues is defined as following:
public class MeaseurementValue
{
public string TestName { get; set; }
public int value { get;set; }
}
Xaml looks like following:
<TextBox HorizontalAlignment="Left" Grid.Column="1" Grid.Row="1" Height="23" Margin="14,20,0,0" TextWrapping="Wrap" Text="{Binding MeasurementValues[0].value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="124" />
So the element in the xaml is bound to an Arrayelement in ViewModel. But when I change that property in text control it does not call the setter of the ViewModel.
I also changed my code that evey element in the array is also notifiable so it looks like following:
public class MeaseurementValue : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string TestName { get; set; }
private int _value;
public int value
{
get { return _value; }
set { _value = value; OnPropertyChanged("value"); }
}
void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
But that also did not work
Is that anything different that we have to do with Arrays as oppose to primitive types?
Upvotes: 0
Views: 1413
Reputation: 22749
The setter gets called, just not the one you expect. In two-way bindings, only the last property in the path gets updated (in the target->source direction).
Think of it like this - if you wrote it in C#, what would you expect to happen?
MeasurementValues[0].value = 1;
What happens here is that first the MeasurementValues
getter is called, then the array indexer's getter is called, but the setter is of the value
property. So there's no reason for the array's setter to ever be called. You're two property accessors away from the MeasurementValues
setter. Even if you write
MeasurementValues[0] = new MeasurementValue();
the MeasurementValues
setter won't be called. Only
MeasurementValues = new ObservableCollection<MeaseurementValue>();
would cause the setter you're referring to be called. It's the exact same thing with bindings. The last item in the property path is the only setter used in a two-way binding. In your case it's the value
property.
If you want to save the configuration each time the value
property is set, you can:
ValueChanged
event in MeaseurementValue
and hook it up when you create each itemUpvotes: 2