views:

74

answers:

1

I'm very new to databinding, and so far have only had luck databinding to element properties in the GUI, or by binding to an ObservableCollection to display lists of data. Now I want to do something different.

I have a method that takes an index and returns a List of doubles, i.e.

List<double> GetValues( int index);

I have a GUI where the user selects the index from a combobox, and then several textboxes need to have their text updated with the values in the List. I actually have a thread running that caches all of this data, because I have UI elements in different places that consume and display the same information. So I figured, why not use databinding? The problem is, I have yet to find a good example online that explains how to take the index from the combobox, call the GetValues method, and then bind the resulting information to all of the textboxes -- all from XAML.

The closest article I've found is http://msdn.microsoft.com/en-us/magazine/cc163299.aspx. Most of the articles I've read talk about using the Source attribute, but then say, "well, the easiest way is to just use StaticResource, so we'll show you that method".

Is this possible, or should I just go back to the easy way of doing this entirely from code-behind?

+1  A: 

The problem you're having is that you're trying to bind to the results from a function, and you may very well complicate things by trying to implement data-binding on something so simple from the code-behind. I'd recommend doing this from the code-behind.

That said, for the simplest and most useful approach, you need to have actual properties in your class to bind to, which you need to update when the index changes. Depending on how you pass the data around, this could reduce the code-behind, or just create more.

Here's an example of what you could end up with:

// Assume 1 of your textboxes displays a weight. Here's the property declaration:
// Disclaimer: Not compiled or tested at all.
public static readonly DependencyProperty WeightProperty = DependencyProperty.Register(
  "Weight", typeof(double), typeof(MyClass), new PropertyMetadata(0.0));

public double Weight
{
  get { return (double)this.GetValue(WeightProperty); }
  set { this.SetValue(WeightProperty); }
}

// Here's an example of setting the property:
private void ComboBoxSelectedIndexChanged(object sender, RoutedEventArgs e)
{
  List<double> values = myObject.GetValues(comboBox.SelectedIndex);
  this.Weight = values[0];
}

// And in your XAML, assuming you've given your Window the name myWindow:
<TextBlock Text="{Binding ElementName=myWindow, Path=Weight}"/>

This can be useful if you plan on updating the Weight property in multiple places and want the TextBlock to always show the correct value.

On the other hand, if your properties will only update in the SelectedIndexChanged function and you don't need the values outside of that function, you may as well have just set the value yourself and reduce the unnecessary overhead:

private void ComboBoxSelectedIndexChanged(object sender, RoutedEventArgs e)
{
  List<double> values = myObject.GetValues(comboBox.SelectedIndex);
  txtWeight.Text = values[0].ToString();
}
Will Eddins
Thanks for the excellent advice! I might end up using a hybrid solution, i.e. I'll create a class with the necessary dependency properties, and the values in this class will get changed in code-behind via the combobox selectionchanged event handler. Then I'll use databinding to access the values. I've yet to see if this approach will make sense for the other part of my GUI.
Dave
Will, I have one other question for you -- everything works great, but now I've added two other objects that I need to databind to. They are the same type as the previous one I was using (that of course is derived from DependencyObject). How do I specify which source I want? I tried to use the Source attribute for Binding, i.e.Text="{Binding Source=_my_object, Path=MyValue}"but although it compiles, it doesn't work -- the text is just blank. What am I doing wrong?
Dave
Set the source in code and set only the path in the binding. `{Binding Path=MyValue}` in XAML, and `myTextBlock.Source = myObject;` in C#
Will Eddins
I ended up doing the first part, but I couldn't set the Source, as that property didn't exist. I did what I've done before, which is to set the DataContext for the higher-level UIElement, and then it picked out the right values for me.
Dave
You're right, `Source` doesn't exist. I meant `DataContext` there, glad to see you figured it out regardless.
Will Eddins