tags:

views:

24

answers:

2

Here's a very simple repro: Start up VS2010 or VS2008, new a WPF project (.Net Framework 3.5 sp1), add an empty page (Page1.xaml) to the project.

The rest code is in MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        TestFrameContent();
    }

    private void TestFrameContent()
    {
        FrameworkElement fe = Activator.CreateInstance(Type.GetType("WpfFrameContentProblem.Page1")) as FrameworkElement;
        Frame frmContainer = new Frame();
        frmContainer.Content = fe;

        Debug.Assert(frmContainer.Content != null, "Content is null");
    }
}

Run the app, it will fail on Debug.Assert, indicate that frmContainer.Content == null.

It's really a mystery to me, that a simple assignment will fail. Anyone?

A: 

See WPF Frame, Content and ContentRendered

Your Frame will however never be rendered since it is not part of any visual tree. Below sample works as expected.

XAML:

<Window x:Class="FrameTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <Frame Name="_frame" />
    </StackPanel>
</Window>

Code behind:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        FrameworkElement fe = Activator.CreateInstance(Type.GetType("WpfFrameContentProblem.Page1")) as FrameworkElement;

        _frame.Content = fe;
        _frame.ContentRendered += 
            (sender, e) => 
                MessageBox.Show("Type of content = " + (sender as Frame).Content.GetType()); 
    }
}
Wallstreet Programmer
A: 

Unfortunately, it is not a simple assignment. Setting the Content property on a Frame actually calls Navigate, which sets the content asynchronously. You will need to handle the Navigated event, which "occurs when the content that is being navigated to has been found, and is available from the Content property, although it may not have completed loading."

private void TestFrameContent()
{
    FrameworkElement fe = Activator.CreateInstance(
        Type.GetType("WpfFrameContentProblem.Page1")) as FrameworkElement;
    Frame frmContainer = new Frame();
    frmContainer.Content = fe;
    frmContainer.Navigated += delegate(object sender, NavigationEventArgs e)
    {
        // This will succeed
        Debug.Assert(frmContainer.Content != null, "Content is null");
    };
}
Quartermeister
Thank you. I guess in this case, I should use ContentControl as my FrameworkElemnt container. Please tell me ContentControl.Content = x is a simple assignment:)
sun1991
@sun1991: Well, it's a dependency property assignment, so I still wouldn't call it "simple". You could have a two-way binding applied to the Content property and the update would be pushed to another object. ContentControl doesn't do value coercion like Frame does, though, so it should at least *act* like a simple property assignment :).
Quartermeister