I'm building a SL4 app. I have two controls, a top search bar and a bottom favorites bar, that I'd like to be present on every page. I'm not sure what the best way to do this is.开发者_运维百科
My current approach uses a nav frame as the root visual:
App.xaml.cs:
this.RootVisual = new NavFrame();
NevFrame.xaml:
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<my:TopSearchBar x:Name="topSearchBar" Grid.Row="0"/>
<navigation:Frame x:Name="navigationFrame" Source="/HomePage.xaml" Grid.Row="1"/>
<my:BottomFavoritesBar x:Name="bottomFavoritesBar" Grid.Row="2"/>
</Grid>
Then, I'd change pages within the Frame, leaving the persistent elements in place. Is this the correct approach, or is there some other preferred pattern?
However, if I do this, I'm not sure how to let the TopSearchBar
and BottomFavoritesBar
user controls do navigation. (In general, I'm not sure how to do navigation directly from a UserControl
.)
When TopSearchBar
was a member of each page, I'd have this code on each page's code-behind:
topSearchBar.ParentPage = this;
TopSearchBar
could then use this reference to do navigation:
ParentPage.NavigationService.Navigate(new Uri("/SearchPage.xaml?q=" + searchBox.Text, UriKind.Relative));
Is there a better way to do this? It feels somewhat awkward. If navigation requires a reference to a page, how can I pass that reference from NavFrame
?
The appropriate approach is to add a dependency property to both the TopSearchBar
and BottomFavoritesBar
called "Navigator" (or whatever you prefer) that has the type INavigate
.
Your xaml would look like this:-
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<my:TopSearchBar x:Name="topSearchBar" Grid.Row="0" Navigator="{Binding ElementName=navigationFrame}"/>
<navigation:Frame x:Name="navigationFrame" Source="/HomePage.xaml" Grid.Row="1"/>
<my:BottomFavoritesBar x:Name="bottomFavoritesBar" Grid.Row="2" Navigator="{Binding ElementName=navigationFrame}" />
</Grid>
Now in your two Bar user controls navigation is simply:-
Navigator.Navigate(new Uri("/SearchPage.xaml?q=" + searchBox.Text, UriKind.Relative));
Edit
To create the dependency properties add this to your TopSearchBar
class:-
public INavigate Navigator
{
get { return GetValue(NavigatorProperty) as INavigate; }
set { SetValue(NavigatorProperty, value); }
}
public static readonly DependencyProperty NavigatorProperty =
DependencyProperty.Register(
"Navigator",
typeof(INavigate),
typeof(TopSearchBar),
new PropertyMetadata(null));
Duplicate this in your BottomFavoritesBar
class but change the reference to TopSearchBar
.
I suggest looking in to Prism CAL Pattern
This way you can create regions for your containers and the region(s) you want changed from page to page... it's simple, you just swap the new one to replace the old one while the others remain in place. It's a much more streamlined approach in my opinion.
http://development-guides.silverbaylabs.org/Video/Silverlight-Prism
精彩评论