2010-08-18 97 views
2

下面是一个非常简单的repro:启动VS2010或VS2008,新建一个WPF项目(.Net Framework 3.5 sp1),向项目添加一个空页面(Page1.xaml)。Frame.Content,赋值操作不起作用?

剩下的代码是在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"); 
    } 
} 

运行的应用程序,它会在Debug.Assert的失败,表明frmContainer.Content == NULL。

这对我来说真的很神秘,一个简单的任务就会失败。任何人?

回答

3

不幸的是,它不是一个简单的任务。在Frame上设置Content属性实际上调用Navigate,它异步设置内容。您需要处理Navigated事件,该事件“在找到正在导航的内容时发生,并且可以从Content属性获得,尽管它可能尚未完成加载。”

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"); 
    }; 
} 
+0

谢谢。 我想在这种情况下,我应该使用ContentControl作为我的FrameworkElemnt容器。请告诉我ContentControl.Content = x是一个简单的作业:) – neolei 2010-08-18 14:34:28

+0

@ sun1991:嗯,这是一个依赖属性赋值,所以我仍然不会称它为“简单”。您可以将双向绑定应用于Content属性,并将更新推送到另一个对象。 ContentControl并不像Frame那样执行值强制操作,所以它至少应该*操作*就像一个简单的属性分配:)。 – Quartermeister 2010-08-18 14:48:36

0

WPF Frame, Content and ContentRendered

你的框架将永远但是被渲染,因为它没有任何可视化树的一部分。下面的示例按预期工作。

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> 

后面的代码:

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()); 
    } 
}