none
Page.DataContext and Framework Navigation

    Question

  • Hi!

    I have a Window that contains a Frame in which I load several Pages. In one of them there are two textboxes data-bounded with the DataContext. When I first load this page, after setting the Page.DataContext property, the data are correctly shown in the textboxes. However, if I use the GoBack/GoForeward buttons, even if I re-assign the DataContext property in the Page_Loaded event, the textboxes remain empty.

    I think that the DataContext is set in the proper way, in fact, if I change the content of textboxes, the object in the DataContext are automatically updated. So, what it the problem?

    Thanks in advance.


    Marco Minerva, marco.minerva@gmail.com
    Tuesday, May 11, 2010 12:04 PM

All replies

  • Marco,

     

    I think that the problem is because when you use GoBack/GoForeward the applicattion don't execute the loaded event again.

    Wednesday, May 12, 2010 12:32 AM
  • No, I have verified and the Loaded event is executed.
    Marco Minerva, marco.minerva@gmail.com
    Wednesday, May 12, 2010 3:20 PM
  • Hi,

    could you post the code where you set the DataContext?


    http://wpfglue.wordpress.com
    Wednesday, May 12, 2010 3:42 PM
  • Hi Marco,

    Do you see any binding error in the output window during debugging?

    A small project that demonstrates the problem will be great.

    Regards,
    Jie
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    If you have any feedback, please tell us.

    The All-In-One Code Framework Project
    My Blog (in Simplified Chinese)
    Thursday, May 13, 2010 6:44 AM
    Moderator
  • Hi,

    I can reproduce the issue with this very simple example (under .Net 4.0; in .Net 3.5 Sp1 the problem doesn't exist):

    <Page x:Class="Page1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:app="clr-namespace:NavigationAndBinding"
      Title="Page1" Loaded="Page_Loaded">
     <!--<Page.DataContext>
      <app:Customer Name="Test"/>
     </Page.DataContext>-->
     <StackPanel>
      <TextBox x:Name="NameTextBox" Text="{Binding Name}"/>
      <TextBlock>
       <Hyperlink NavigateUri="Page2.xaml">Go to Page 2</Hyperlink>
      </TextBlock>
      </StackPanel>
    </Page>
    
    <Page x:Class="Page2"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"
      Title="Page2">
     <StackPanel>
      <TextBlock HorizontalAlignment="Center">In Between...</TextBlock>
      <TextBlock>
       <Hyperlink NavigateUri="Page1.xaml">Go to Page 1</Hyperlink>
      </TextBlock>
     </StackPanel>
    </Page>
    
    <NavigationWindow x:Class="MainWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Title="MainWindow" Height="350" Width="525" Source="Page1.xaml"/>
    
    

     

    This it the Customer Class:

    Public Class Customer
     Implements System.ComponentModel.INotifyPropertyChanged
    
     Protected Overridable Sub OnPropertyChanged(ByVal ParamArray propertynames() As String)
      If propertynames.Length = 0 Then
       RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(""))
      Else
    
       For Each propertyName As String In propertynames
        RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(propertyName))
       Next
      End If
     End Sub
    
     Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
     Private _Name As String
     Private _Address As String
     Private _City As String
     Private _Country As String
    
     Public Property Name() As String
      Get
       Return _Name
      End Get
      Set(ByVal value As String)
       _Name = value
       OnPropertyChanged("Name")
      End Set
     End Property
    
     Public Property Address() As String
      Get
       Return _Address
      End Get
      Set(ByVal value As String)
       _Address = value
       OnPropertyChanged("Address")
      End Set
     End Property
     Public Property City() As String
      Get
       Return _City
      End Get
      Set(ByVal value As String)
       _City = value
       OnPropertyChanged("City")
      End Set
     End Property
     Public Property Country() As String
      Get
       Return _Country
      End Get
      Set(ByVal value As String)
       _Country = value
       OnPropertyChanged("Country")
      End Set
     End Property
    
    End Class

    The problem seems to be that the bindings in a page are not restored when reaching ot through backwards navigation. At least Snoop shows that the DataContext is set, while the value of the TextBox is not set.

    I'm posting this on connect... It doesn't make a difference whether the DataContext is set in XAML or in the Loaded event of Page1.


    http://wpfglue.wordpress.com
    Saturday, May 22, 2010 4:57 PM
  • Hi,

    I found a workaround for this problem: just wrap the contents of the page into a UserControl, like this:

    <Page x:Class="Page1"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:app="clr-namespace:NavigationAndBinding"
       xmlns:s="clr-namespace:System;assembly=mscorlib"
       Title="Page1" Loaded="Page_Loaded"
       x:Name="Page">
      <Page.Resources>
        <ObjectDataProvider x:Key="customer" ObjectType="{x:Type app:Customer}">
          <ObjectDataProvider.ConstructorParameters>
            <s:String>Test</s:String>
          </ObjectDataProvider.ConstructorParameters>
        </ObjectDataProvider>
        <DataTemplate x:Key="customerTemplate" DataType="{x:Type app:Customer}">
          <StackPanel>
            <TextBox x:Name="NameTextBox" Text="{Binding Name}"/>
            <TextBlock>
          <Hyperlink NavigateUri="Page2.xaml">Go to Page 2</Hyperlink>
            </TextBlock>
          </StackPanel>
        </DataTemplate>
      </Page.Resources>
      <!--<Page.DataContext>
        <app:Customer Name="Test"/>
      </Page.DataContext>-->
      <StackPanel>
        <app:CustomerView/>
      </StackPanel>
    </Page>
    
    <UserControl x:Class="CustomerView"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
           mc:Ignorable="d" 
           d:DesignHeight="300" d:DesignWidth="300">
      <StackPanel>
        <TextBox x:Name="NameTextBox" Text="{Binding Name}"/>
        <TextBox x:Name="JournalTest"/>
        <TextBlock x:Name="LinkBlock">
          <Hyperlink x:Name="Link" NavigateUri="Page2.xaml">Go to Page 2</Hyperlink>
        </TextBlock>
      </StackPanel>
    </UserControl>
    

    http://wpfglue.wordpress.com
    Sunday, May 23, 2010 1:44 PM
  • Hi

    I have a Window that contains a Frame in which I load several Pages, How do i remove or close the selected page from the frames

    Tuesday, June 19, 2012 11:15 AM