Silverlight 3用户控件之间的导航?

时间:2009-12-15 19:22:25

标签: c# silverlight silverlight-3.0 navigation

我刚开始接触来自ASP.NET和Flex的silverlight 3。

我已经按照新的导航教程here阅读了身份验证和角色管理教程。

所以,我有一个主页面,它有一个框架,在网格内部,以及几个视图。这些都是可导航的并且工作正常。我认为这个主页是我想到的小应用程序的主页。

所以我知道我想拥有一个login.xaml UserControl。这将处理所有登录,一旦经过身份验证,我想导航到MainPage,并使用它的框架从那里开始。

我不想仅仅使用登录作为我框架中的单独页面,因为我希望登录使用与应用程序其余部分不同的网格,也可以单独使用。

那么我如何从一个用户控件(Login)导航到另一个(Main)?

我试过了

 private void btnLogin_Click(object sender, RoutedEventArgs e)
    {
        //TO - DO: All the auth work, just want navigation sorted first

        this.Visibility = Visibility.Collapsed;
        App.Current.RootVisual = new MainPage(); 
    }

没有运气。我也试过尝试一个新的主要并设置它的可见性,但这当然不起作用。

我是否以正确的方式接近这个?

非常感谢。

编辑 - 在进一步挖掘之后好了,this看起来像是一种方法,可以做后续的事情,但它确实感觉有点hackish!这是siverlight 3的建议方式吗?再次感谢

2 个答案:

答案 0 :(得分:2)

我通常做的是创建一个类型为System.Windows.Controls.Navigation的“MainPage.xaml”。它被分配给我的应用程序的RootVisual属性;除了导航框架外,它几乎是空的:

<navigation:Page 
x:Class="Client.MainPage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
mc:Ignorable="d" 
d:DesignWidth="400" 
d:DesignHeight="400" MinWidth="700" MinHeight="480"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Title="Main SlideLinc Page">
<Grid x:Name="LayoutRoot">
    <navigation:Frame x:Name="rootFrame" />
</Grid>
</navigation:Page>

然后我使用“rootFrame”导航框来处理我的所有导航需求,例如,使用静态NavigationManager类中的这些方法:

    public static void Navigate(string url, Action<Exception, UIElement> callback)
    {
        Navigate(new Uri(url, UriKind.RelativeOrAbsolute), callback);
    }

    public static void Navigate(Uri uri, Action<Exception, UIElement> callback)
    {
        if (rootFrame == null)
        {
            Logger.LogMessage("Can't use navigation, because rootFrame is null");
            ErrorMessageBox.Show(ClientStrings.NavigationFailed);
        }
        else
        {
            NavigatedEventHandler successHandler = null;
            NavigationFailedEventHandler failureHandler = null;
            successHandler = (s, e) =>
                 {
                     rootFrame.Navigated -= successHandler;
                     rootFrame.NavigationFailed -= failureHandler;
                     if (callback != null)
                     {
                         callback(null, e.Content as UIElement);
                     }
                 };
            failureHandler = (s, e) =>
                {
                    rootFrame.Navigated -= successHandler;
                    rootFrame.NavigationFailed -= failureHandler;
                    if (callback != null)
                    {
                        callback(e.Exception, null);
                    }
                };
            rootFrame.Navigated += successHandler;
            rootFrame.NavigationFailed += failureHandler;
            rootFrame.Navigate(uri);
        }
    }

因此,在您的情况下,您可以使用它:

NavigationManager.Navigate(new Uri("/Login.xaml", UriKind.Relative), null);

或者:

NavigationManager.Navigate(new Uri("/Home.xaml", UriKind.Relative), (error, element) => InitializeElement(element));

答案 1 :(得分:2)

SL3中有3种类型的容器

  1. 页面(视图)
  2. 用户控件
  3. ChildWindows(Popups)
  4. 不要交换UserControls,这是一个坏主意,它基本上意味着清除“MainPage”内容和添加新的UserControl。通过这样做,你失去了浏览器的Back / Forth行为,因为URL永远不会改变,这不是导航框架的设计方式,而是交换Pages(views)通过使用NavigationService来实现这一点。

    private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            //TO - DO: All the auth work, just want navigation sorted first
    
            NavigationService.Navigate(new Uri("/HomePage.xaml", UriKind.Relative));
        }
    

    现在HomePage.xaml是一个页面(不是UserControl),在启动时,NavigationFrame的默认加载页面应该是您的登录页面。

    UserControls是可重用的功能,可以部署在多个页面上。