Search code examples
c#wpfframedatacontext

Is it possible to access the DataContext of the current page of the frame? How?


In wpf, is it possible to access the DataContext of the current page of the frame? If YES, how?

If NO, what should I use as replacement for frame so that I can access its DataContext?

If something is not clear, please tell me.

Update: For Clarification

I have a Frame in MainWindow.xaml. I want to access the DataContext of the current page displayed in the Frame. Let's just say I want to display a string property named title of the ViewModel of the current page. (Let's assume that each page' ViewModel has title property)

Update: Here is my MainWindow.xaml

<Window x:Class="Libertalia.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        .
        .
        .
        DataContext="{Binding Main, Source={StaticResource Locator}}"
        >
        <ScrollViewer VerticalScrollBarVisibility="Auto">
            <Grid>
                <Frame Panel.ZIndex="1" x:Name="MainFrame" JournalOwnership="OwnsJournal" NavigationUIVisibility="Hidden" Source="View/BlankPage.xaml" />
            </Grid>
        </ScrollViewer>
</Window>

Code of the page (just one of it, just a sample):

<Page x:Class="Libertalia.View.LoginView"
      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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
      xmlns:behaviors="clr-namespace:Libertalia.Behavior"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      .
      .
      .
      DataContext="{Binding Page1, Source={StaticResource Locator}}"
    <DockPanel Margin="200" >

    </DockPanel>
</Page>

UPDATE: Model, View and ViewModel Relationship

  • MainWindow.xaml (View) is binded to MainViewModel.cs (ViewModel). In short, MainWindow.xaml's DataContext is MainViewModel.cs

  • MainWindow.xaml (View) has Frame

  • Frame has Page (View). Frame has many Pages, displayed one at a time.
  • Page has its own ViewModel (DataContext)

What I want to do:

  • Access current page' (of the Frame) DataContext from the DataContext of the MainWindow (MainViewModel).

Solution

  • I'm not sure that it will work for you, because I still don't understand the relationship between view models and models in your architecure, but try to use this idea:

    1). My Window1's xaml has following content :

    <Grid>       
        <Frame Panel.ZIndex="1"
               x:Name="MainFrame"
               JournalOwnership="OwnsJournal"
               NavigationUIVisibility="Hidden"
               Source="UserControl1.xaml" />
    </Grid>
    

    2) UserControl1 has definition of DataContext:

     public UserControl1()
        {
            InitializeComponent();
            DataContext = new MainViewModel();
        }
    

    3). The code where I extract and modfy the DataContext of the Content of my Frame:

       Window1 window = new Window1();
            //window.Content = uc;
    
    
            var aa = window.Content as Grid;
    
            foreach (var e in aa.Children)
            {
                if (e is Frame)
                {
                    Frame f = e as Frame;
                    f.ContentRendered += F_ContentRendered;
                }
            }
    
    //only inside of handler of ContentRendered event you can access to the content of your Frame:
      private void F_ContentRendered(object sender, EventArgs e)
        {
            var frame = sender as Frame;
            UserControl1 uc1 = frame.Content as UserControl1;
            MainViewModel mvm = uc1.DataContext as MainViewModel;
    
        }
    

    It should work.