3

I'm having a rather frustrating problem here... I have a WPF Page that contains a TabControl, and the content of the various TabItems is another WPF Page (hosted in a Frame because Page can only have Frame or Window as a parent). Even though the FlowCalibrationSummaryView is being displayed, everything on it is empty because the data binding of the SummaryViewModel is not working for some reason. Here's part of the XAML:

<TabControl Grid.Row="0">
    <TabItem Header="Current Calibration">
        <TabItem.Content>
            <Frame>
                <Frame.Content>
                    <view:FlowCalibrationSummaryView DataContext="{Binding SummaryViewModel}"/>
                </Frame.Content>
            </Frame>
        </TabItem.Content>
    </TabItem>
</TabControl>

I have a break point on the get of SummaryViewModel, and it is only getting hit by the code that is constructing it in the parent view model. Here's the property being bound to:

    public const string SummaryViewModelPropertyName = "SummaryViewModel";
    private FlowCalibrationSummaryViewModel _SummaryViewModel;
    public FlowCalibrationSummaryViewModel SummaryViewModel
    {
        get { return _SummaryViewModel; }
        set
        {
            if (_SummaryViewModel == value)
                return;

            _SummaryViewModel = value;
            RaisePropertyChanged(SummaryViewModelPropertyName);
        }
    }

At this point I'm completely stumped, I cannot for the life of me figure out why this binding is not working. Any help would be much appreciated.

Update: It definitely has something to do with it being in a Frame. I tried changing the FlowCalibrationSummaryView to a UserControl instead of a Page to see if that helped, and it didn't, then I tried taking it out of the Frame it was wrapped in and that worked. All of the views in my project are done as Pages so for consistency's sake I'd prefer this to be a Page, but then I have to host it in a Frame. Is there something I'm missing here, or is the proper usage to do it as a UserControl?

StuartMorgan
  • 658
  • 5
  • 28
  • When you analyze your application with [Snoop](https://snoopwpf.codeplex.com/), what is displayed as the data context of the `FlowCalibrationSummaryView` if you do *not* explicitly assign anything to the `DataContext` property? – O. R. Mapper Apr 14 '15 at 17:34
  • An alternate way to associate the view model to the view is to reference the view model within the constructor of the view. Then set the data context of the view to the view model explicitly. – MikeG Apr 14 '15 at 17:41
  • 1
    FWIW, I typically use UserControls for all my subviews, and no extra `Frame` containers are necessary. – mclark1129 Apr 14 '15 at 17:44
  • Could we see your `INotifyPropertyChanged` implementation for `RaisePropertyChanged`? Similarly to @MikeC I use `UserControl` for the container of my Views. Works flawlessly thus far. – B.K. Apr 14 '15 at 17:44
  • Also, can you verify that DataContext is null on the `FlowCalibrationSummaryView`? – mclark1129 Apr 14 '15 at 17:45
  • The INotifyPropertyChanged implementation is fine, it's the same code I use everywhere. The problem is due to the Frame wrapping the Page. I read in another post that the binding doesn't update if the DataContext is changed when hosted inside a Frame, I just don't understand why that would be. I think I'm just going to go ahead and stick to the view being a UserControl so that it doesn't have to be hosted in a Frame. – StuartMorgan Apr 14 '15 at 17:49

1 Answers1

2

I would take a look at the answer provided in this question. It seems to provide a specific explanation of the behavior of Frame in this case.

Unless there is a specific reason you have chosen Frame over UserControl, you would be better off re-implementing this (and any other sub-view) as UserControl instead.

Community
  • 1
  • 1
mclark1129
  • 7,532
  • 5
  • 48
  • 84
  • Hmm, never knew of this odd behavior... but then again, I never had a need for `Frame`. – B.K. Apr 14 '15 at 17:50