0

Data templates are great, but I'm having a problem with binding in a particular situation. I have a class, Value, that has various descendants like StringValue, DateValue, etc. These Values show up in a Listbox. This template works fine, binding to a specific property of StringValue:

<DataTemplate DataType="{x:Type values:StringValue}">
    <TextBox Margin="0.5"
             Text="{Binding Path=Native}" />
</DataTemplate>

However, when I bind to an object itself, instead of a specific property, the changes don't update the object, as in this template:

<DataTemplate DataType="{x:Type values:LookupValue}">
    <qp:IncrementalLookupBox SelectedValue="{Binding Path=., Mode=TwoWay}"
         LookupProvider="{Binding ElementName=EditWindow, Path=ViewModel.LookupProvider}">
    </qp:IncrementalLookupBox>
</DataTemplate>

IncrementalLookupBox is a UserControl that ultimately allows a user to select a LookupValue, which should replace the item bound in the template. If this was bound to a simple type like an int or string, the binding would replace the object, so I'm not sure what the difference is with a more complex object. I know that the IncrementalLookBox is working, because binding some textboxes to the properties of SelectedValue (which is a dependency property) shows the correctly selected LookupValue.

In case it makes the situation more clear, here is the implementation of SelectedValue:

    public LookupValue SelectedValue
    {
        get { return (LookupValue)GetValue(SelectedValueProperty); }
        set { SetValue(SelectedValueProperty, value); }
    }

    // Using a DependencyProperty as the backing store for SelectedValue.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SelectedValueProperty =
        DependencyProperty.Register("SelectedValue", typeof(LookupValue), typeof(IncrementalLookupBox), new PropertyMetadata(OnSelectedValuePropertyChanged));

    private static void OnSelectedValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var obj = d as IncrementalLookupBox;
        obj.OnSelectedValuePropertyChanged(e);
    }

    private void OnSelectedValuePropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        CheckForSelectedValueInLookups();
    }
  • hmmm.... do you need a complete path on SelectedValue binding? –  Mar 25 '15 at 00:42
  • It sounds like your `LookupValue` has it's property notifications not firing properly. When the `SelectedItem` changes on the `IncrementalLookupBox`, it needs to fire OnPropertyChanged for the LookupValue. – Johnathon Sullinger Mar 25 '15 at 03:52
  • You're much better off using the `SelectedItem` property instead of the `SelectedValue` property as the `SelectedItem` property is used with an object whereas the `SelectedValue` property is typically used for a property value from an object... it should be used in conjunction with the `SelectedValuePath` property. See the [How to: Use SelectedValue, SelectedValuePath, and SelectedItem](https://msdn.microsoft.com/en-us/library/ms788714(v=vs.110).aspx) page on MSDN for further information. – Sheridan Mar 25 '15 at 09:00
  • Please see ["Should questions include “tags” in their titles?"](http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles), where the consensus is "no, they should not"! –  Mar 25 '15 at 09:32
  • @Sam: I am trying to bind to the entire object, not a specific property. – Steve Pietrykoski Mar 25 '15 at 19:14
  • @Sheridan: IncrementalLookupBox is my own UserControl, not a derivative of Listbox. I've already run into the issues you raise in another context though. – Steve Pietrykoski Mar 25 '15 at 19:19
  • @JohnathonSullinger: Being implemented as a dependency property, I do not believe I need to additionally fire off an OnPropertyChanged. I have textboxes that are bound to SelectedValue.Native and SelectedValue.Display, and they update as expected. But the object bound in the template does not change. – Steve Pietrykoski Mar 25 '15 at 19:31
  • My issue is the same as described here: http://stackoverflow.com/questions/13953962/wpf-twoway-binding-of-listbox-using-datatemplate. – Steve Pietrykoski Mar 28 '15 at 22:52

3 Answers3

0

If all else fails consider using a ValueConverter to get the value you require.

Scott Nimrod
  • 11,206
  • 11
  • 54
  • 118
0

Edit: this does not work. See link in comments below.

Make sure your class implements INotifyPropertyChanged and raise PropertyChanaged here:

 private void OnSelectedValuePropertyChanged(DependencyPropertyChangedEventArgs e)
 {
     CheckForSelectedValueInLookups();
     // RaisePropertyChanged();
 }
  • I tried just to make sure, but nothing changed. Everything I've read says you don't need INotifyPropertyChanged with dependency properties. – Steve Pietrykoski Mar 26 '15 at 18:55
  • See my answer to this question: http://stackoverflow.com/questions/2480366/how-to-raise-property-changed-events-on-a-dependency-property the response marked as answer does not work –  Mar 26 '15 at 20:24
  • I think I told you wrong in my response - I apologize. I have been working on web stuff for several months and at my age it leaves my brain quickly. –  Mar 26 '15 at 20:30
  • Thanks for trying to help, Sam. I still have no luck with this. If I succeed in making a simple case that demonstrates the issue, should I add the code to this question or start a new one? – Steve Pietrykoski Mar 27 '15 at 19:15
  • Post to this thread. Be sure to show where you set DataContext. –  Mar 27 '15 at 21:36
0

My issue is the same as described here:

WPF TwoWay Binding of ListBox using DataTemplate

Apparently if I don't write enough text here, my answer will be converted to a comment and not close out the question. So, to summarize the issue, a two-way Binding=. in a datatemplate used in a ListBox (or any ItemsControl I image) won't work, because it is not the object itself being bound, but the ListBoxItem that contains it.

Community
  • 1
  • 1