Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding to an array element

I'm trying to bind a TextBlock to a specific element in an ObservableCollection. This is what I do right now:

private ObservableCollection<double> arr = new ObservableCollection<double>();
public ObservableCollection<double> Arr { get { return arr; } set { arr = value; }  }

testBox.DataContext = this;

private void Button_Click(object sender, RoutedEventArgs e)
{
   Arr[0] += 1.0;
}

    [ValueConversion(typeof(ObservableCollection<double>), typeof(String))]
    public class myObsCollConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ObservableCollection<double> l = value as ObservableCollection<double>;
            if( l == null )
                return DependencyProperty.UnsetValue;
            int i = int.Parse(parameter.ToString());

            return l[i].ToString();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return DependencyProperty.UnsetValue;
        }
    }


    <Window.Resources>
        <local:myObsCollConverter x:Key="myConverter"/>
    </Window.Resources>

        <TextBlock Name="testBox" Text="{Binding Path=Arr,Converter={StaticResource myConverter}, ConverterParameter=0}" />

What I see is that testBox shows the first value of Arr when it is created. But it doesn't reflect any changes to this element. What do I have to do in order to see changes to Arr[0] in my textBox?

like image 681
MTR Avatar asked Mar 24 '11 07:03

MTR


2 Answers

No need for the converter. You can bind directly to Arr[0] like this

 <TextBlock Name="testBox" Text="{Binding Path=Arr[0]}"/>

The elements in Arr would need to implement INotifyPropertyChanged though in order to dynamically update.

Update: To elaborate a bit more:

public class MyDouble : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private double _Value;
    public double Value 
    { 
        get { return _Value; } 
        set { _Value = value; OnPropertyChanged("Value"); }
    }

    void OnPropertyChanged(string propertyName)
    {
       var handler = PropertyChanged;
       if (handler != null)
       {
          handler(this, new PropertyChangedEventArgs(propertyName));
       }
    }
}

and then

 ObservableCollection<MyDouble> Arr { get; set; }

and bind to

 <TextBlock Name="testBox" Text="{Binding Path=Arr[0].Value}"/>
like image 52
ChrisWue Avatar answered Oct 13 '22 01:10

ChrisWue


ObservableCollections do not propagate changes to values stored within objects that belong to the collection. It only fires off the notifications when the content of the collection itself changes (ie. item added, removed, reordered). If you want to make it so that your UI updates when values within the collection changes then you'll have to wire that up yourself separately.

like image 23
OJ. Avatar answered Oct 12 '22 23:10

OJ.