0
votes

I'm having difficulty getting the binding to fire off on a user control that is nested inside of another use control. Here is my hierarchy:

  • Navigation Page
    • User Control A (AthleteMaxGrid)
      • User Control B (PagingControl)

I'm using the MVVM design model with the MVVMLight toolkit for these controls. Here is the situation: Both User Controls have corresponding ViewModels that are attached to them in the XAML. The View Model of AthleteMaxGrid has a Observable Collection (AthleteMaxes) property exposed that I wanted to bind to the PagingControl. This property is also being bound to in a dataview in the AthleteMaxGrid control, so it know its being populated correctly.

Here is the code:

AthleteMaxGrid XAML:

     <UserControl ...
         DataContext="{Binding AthleteMaxGrid, Source={StaticResource Locator}}">
     ....
     <StackPanel Orientation="Horizontal">
        ...
        <my:PagingControl Jake="{Binding AthleteMaxes}" />
    </StackPanel>
    <telerik:RadGridView x:Name="rgvMaxes" IsScrolling="False" 
        ItemsSource="{Binding AthleteMaxes}" AutoGenerateColumns="False" 
        IsBusy="{Binding IsBusy}" >...

Here is a snipit from the AthleteMaxGrid ViewModel:

public const string AllMaxesPropertyName = "AthleteMaxes";

private ObservableCollection<AthleteMaxTableItem> _allMaxes = new ObservableCollection<AthleteMaxTableItem>();

    /// <summary>
    /// Gets the AthleteMaxes property.
    /// </summary>
    public ObservableCollection<AthleteMaxTableItem> AthleteMaxes
    {
        get
        {
            return _allMaxes;
        }

        set
        {
            if (_allMaxes == value)
            {
                return;
            }

            _allMaxes = value;

            // Update bindings, no broadcast
            RaisePropertyChanged("AthleteMaxes");
        }
    }

Here is the XAML from PagingControl:

<UserControl  ...
          x:Name="rootElement"
         DataContext="{Binding PagingControlVM, Source={StaticResource Locator}}">
 ...
</UserControl>

And I created the Dependency property in the PagingControl code behind like this:

    public const string JakePropertyName = "Jake";

    public object Jake
    {
        get
        {
            return (object)GetValue(JakeProperty);
        }
        set
        {
            SetValue(JakeProperty, value);
        }
    }

    public static readonly DependencyProperty JakeProperty = DependencyProperty.Register(
        JakePropertyName,
        typeof(object),
        typeof(PagingControl),
        new PropertyMetadata(null,
            new PropertyChangedCallback(onJakeChanged)));


    private static void onJakeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MessageBox.Show(d.GetType().ToString());
    }

At this point i'm just trying to get my Callback function hit (onJakeChanged) so I know the data is coming in properly and I can move to the next stage of binding my controls, however it is not getting hit.

If I set the Jake Property in the XAML on the AthleteMaxGrid to something simple like "test" then the callback is hit properly. It seems to be a problem with the binding of the viewModel property.

Any ideas?

Thanks in advance! Nick

1
Whenever I get binding issues I add a load of TextBlocks with all sorts of debug bindings in them to see what the properties are. So a TextBlock with Text="{Binding}" will ensure that you're actually bound to something and will tell you what type you're bound to (so you can check that the AthleteMaxes property actually exists on that type. Text="{Binding AthleteMaxes}" will tell you if that property is null or not. - BenCr
Great idea. I've never tried that before and I was definitely getting frustrated at the difficulty of figuring out binding issues. I'll give it a whirl.Thanks! - Nick

1 Answers

0
votes

This one is simple to answer. This line here:

<my:PagingControl Jake="{Binding AthleteMaxes}" />

will bind Jake to the DataContext's AthleteMaxes. But you are setting the DataContext to something else when the UserControl is created!

<UserControl x:Name="rootElement" DataContext="{Binding PagingControlVM, Source=StaticResource Locator}}">

So now Jake is bound to PagingControlVM.AthleteMaxes ... which doesn't exist :)