我正在处理欢迎屏幕,它可以导航使用主窗口中的“框架”控件显示的 5 个页面。
现在我需要 x:bind 一些控件到主窗口的视图模型,因为我不想为所有 5 个页面创建 5 个视图模型。那么如何实现呢?或者如何将主窗口的视图模型对象传递给5个页面
主窗口:WelcomeScreen.xaml
<Window
x:Class="WelcomeScreen.WelcomeScreen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WelcomeScreen"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="">
<Grid ColumnDefinitions="*,*,*" RowDefinitions="*" >
<StackPanel Grid.Column="0" Grid.ColumnSpan="3" Orientation="Vertical" >
<Frame x:Name="NavigationFrame" />
<Line Stroke="LightGray" X1="0" Y1="0" X2="1200" Y2="0" StrokeThickness="2" Margin="12,0,12,0"/>
<RelativePanel>
<CheckBox x:Name="DoNotShowAaginCheckBox" Content="Don't show this again" FontFamily="{StaticResource VeneerFont}" Checked="{x:Bind ViewModel.OnChecked}" Unchecked="{x:Bind ViewModel.OnChecked}" Visibility="{x:Bind ViewModel.IsCheckBoxVisible,Mode=OneWay}" Margin="12,12,0,0" RelativePanel.AlignLeftWithPanel="True" />
<Button x:Name="BackButton" Width="100" Style="{StaticResource AccentButtonStyle}" FontFamily="{StaticResource VeneerFont}" Click="{x:Bind ViewModel.BackButton_Click}" RelativePanel.AlignLeftWithPanel="True" Content="Back" Visibility="{x:Bind ViewModel.IsBackButtonVisible,Mode=OneWay}" Margin="12,12,12,0"/>
<PipsPager x:Name="PipsPager" Margin="0,15,0,0" NumberOfPages="{x:Bind ViewModel.WelcomeScreenPageList.Count}" SelectedPageIndex="{x:Bind ViewModel.CurrentPageIndex, Mode=TwoWay}" RelativePanel.AlignHorizontalCenterWithPanel="True" SelectedIndexChanged="Pager_SelectedIndexChanged" />
<Button x:Name="NextButton" Width="100" Style="{StaticResource AccentButtonStyle}" FontFamily="{StaticResource VeneerFont}" Click="{x:Bind ViewModel.NextButton_Click}" Content="{x:Bind ViewModel.NextButtonText,Mode=OneWay}" RelativePanel.AlignRightWithPanel="True" Margin="0,12,12,0"/>
</RelativePanel>
</StackPanel>
</Grid>
WelcomeScreen.xaml.cs:
public sealed partial class WelcomeScreen : Window
{
internal WelcomeScreenPageViewModel ViewModel { get; set; }
public WelcomeScreen(object viewModel) : this()
{
if (viewModel == null || viewModel.GetType() != typeof(WelcomeScreenPageViewModel))
return;
ViewModel = viewModel as WelcomeScreenPageViewModel;
}
public WelcomeScreen()
{
this.InitializeComponent();
this.InitializeControls();
}
public void Pager_SelectedIndexChanged(object sender,PipsPagerSelectedIndexChangedEventArgs e)
{
bool isForward = false;
if (ViewModel.CurrentPageIndex > ViewModel.PreviousPageIndex)
isForward = true;
ViewModel.PreviousPageIndex = ViewModel.CurrentPageIndex;
Type pagetype = Type.GetType(ViewModel.WelcomeScreenPageList[ViewModel.CurrentPageIndex]);
if (isForward)
{
NavigationFrame.Navigate(pagetype,
null,
new SlideNavigationTransitionInfo()
{ Effect = SlideNavigationTransitionEffect.FromRight });
}
else
{
NavigationFrame.Navigate(pagetype,
null,
new SlideNavigationTransitionInfo()
{ Effect = SlideNavigationTransitionEffect.FromLeft });
}
ViewModel.UpdateControls();
}
}
第1页:
<Page
x:Class="WelcomeScreen.WelcomeScreenPage1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WelcomeScreen"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource SystemControlBackgroundChromeWhiteBrush}">
<Grid ColumnDefinitions="*" RowDefinitions="*,*" >
HorizontalAlignment="Right" Grid.Row="0" Margin="0,5,5,0"/>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<TextBlock x:Name="PageText" Text="{x:Bind WelcomeScreenPageViewModel.xxx? , Mode=OneWay}""/>
</StackPanel>
</Grid>
</Page>
WelcomeScreenPage1.xaml.cs:
public sealed partial class WelcomeScreenPage1 : Page
{
public WelcomeScreenPage1()
{
this.InitializeComponent();
}
}
您可以在导航后立即设置 ViewModel:
假设您有 2 页:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Button
Click="Page1Button_Click"
Content="Page 1" />
<Button
Click="Page2Button_Click"
Content="Page 2" />
</StackPanel>
<Frame
x:Name="ContentFrame"
Grid.Row="1" />
</Grid>
public sealed partial class Page1 : Page
{
public Page1()
{
this.InitializeComponent();
}
public PageViewModel ViewModel { get; set; }
}
public sealed partial class Page2 : Page
{
public Page2()
{
this.InitializeComponent();
}
public PageViewModel ViewModel { get; set; }
}
然后你可以这样做:
private void Page1Button_Click(object sender, RoutedEventArgs e)
{
this.ContentFrame.Navigate(typeof(Page1));
(this.ContentFrame.Content as Page1).ViewModel = new PageViewModel { Title = "Page 1" };
}
private void Page2Button_Click(object sender, RoutedEventArgs e)
{
this.ContentFrame.Navigate(typeof(Page2));
(this.ContentFrame.Content as Page2).ViewModel = new PageViewModel { Title = "Page 2" };
}