x:将嵌入页面绑定到WinUi 3中的父窗口视图模型

问题描述 投票:0回答:1

我正在处理欢迎屏幕,它可以导航使用主窗口中的“框架”控件显示的 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();
    }
}
c# mvvm binding winui-3 xbind
1个回答
0
投票

您可以在导航后立即设置 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" };
}
© www.soinside.com 2019 - 2024. All rights reserved.