C# Xamarin Forms 主从页面 MVVM

3
我有一个Xamarin Forms应用程序,其根视图为Master Detail Page,正在实现MVVM模式。
我的Root Page加载了一个Detail Page和一个Master Page。Detail Page被包装在导航页面中,Master Page用于显示链接到详情页面的菜单。
Master Page使用List View来展示导航菜单,Detail Page则保存来自Master Page的所有选定项,它会显示一个新的内容页面。
我希望我的detail页面使用其自己的ContentPage Content属性来展示来自Master Page的选定页链接。我想知道是否可能,如果不行,有哪些替代方法。
以下是我的MasterDetailPage的ViewModel。
    public class PageViewModel: ViewModelBase 
    {
    public event EventHandler<string> ItemSelectedEventHandler;
    string _selectedpagelink;
    public string SelectedPageLink
    {
        get { return _selectedpagelink; }
        set
        {
            if (_selectedpagelink != value)
            {
                _selectedpagelink = value;
                OnItemSelected(this,value);
                OnPropertyChanged();
            }
        }
    }




    public ObservableCollection<string> Links => 
    new   ObservableCollection<string>
    {
        "PageOne",
        "PageTwo"
    };

    public PageViewModel()
    {
        this.SelectedPageLink = this.Links.FirstOrDefault();
    }

    protected virtual void OnItemSelected(object sender , string newPage)
    {
        ItemSelectedEventHandler?.Invoke(this, newPage);
    }


}

这里是我的转换器,它将页面值转换为字符串,这样就可以使用资源字典进行导航。

    public object Convert(object value, Type targetType, object  parameter, CultureInfo culture)
    {
        var key = value as string;
        if (key == null)
        {
            throw new ArgumentNullException("Resource key is not found", nameof(value));
        }

        return Application.Current.Resources[key];
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

这是我的主控页面,使用了内容页面和列表视图。

 **<ListView 
              x:Name="ListViewMenuMaster"
              ItemsSource="{Binding Links}"
              SelectedItem="{Binding SelectedPageLink}"

              SeparatorVisibility="None"
              HasUnevenRows="true">

            <ListView.Header>
                <Grid BackgroundColor="#03A9F4">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="10"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="10"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="30"/>
                        <RowDefinition Height="80"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="10"/>
                    </Grid.RowDefinitions>
                    <Label
              Grid.Column="1"
              Grid.Row="2"
              Text="My App Name here"
              Style="{DynamicResource SubtitleStyle}"/>

                </Grid>
            </ListView.Header>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Padding="15,10" HorizontalOptions="FillAndExpand">
                            <Label VerticalOptions="FillAndExpand" 
                    VerticalTextAlignment="Center" 
                    Text="{Binding}"

                    FontSize="24"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>**

这是我的详细页面,应该显示来自主页面的所选链接

 **<ContentPage.BindingContext>
        <vm:PageViewModel />
    </ContentPage.BindingContext>
    <ContentPage.Resources>
        <ResourceDictionary>
            <conv:ResourceLookUpConverter x:Key="resourceLookupConverter"/>
        </ResourceDictionary>
    </ContentPage.Resources>

     *Can the content property below be used to display the selected page links???*
    <ContentPage Content="{Binding SelectedPageLink, Converter={Binding resourceLookupConverter}}" />**

我要导航到的内容页面是非常简单的Content Page类型。我希望在不让ViewModel知道任何有关视图的情况下完成此操作。我认为我已经实现了这一点,但我的担忧是Content Page Content属性能否显示所选的Master Page链接?

1个回答

3

我不知道我是否正确理解了您的需求。如果您想在选择 SelectedPageLink 时打开 ContentPage(详细信息),我认为您可以使用 MessagingCenter(希望它遵循 MVVM 约定...)

请查看此repo

这里有一个 MasterPage,在代码后台中有这段代码

    protected override void OnAppearing()
    {
        MessagingCenter.Subscribe<MasterPageViewModel, string>(this, "Detail", (arg1, arg2) => {

            ((MasterDetailPage)Application.Current.MainPage).Detail = new DetailPage(arg2);
            ((MasterDetailPage)Application.Current.MainPage).IsPresented = false;
        });
        base.OnAppearing();
    }

    protected override void OnDisappearing()
    {
        MessagingCenter.Unsubscribe<MasterPageViewModel, string>(this, "Detail");
        base.OnDisappearing();
    }

当列表中选择了一个项目时,它从其ViewModel接收到一条消息。

    public MyModel SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            if (_selectedItem != null)
                _selectedItem.Selected = false;

            _selectedItem = value;

            if (_selectedItem != null)
            {
                _selectedItem.Selected = true;
                MessagingCenter.Send<MasterPageViewModel, string>(this, "Detail", _selectedItem.Name);
            }
        }
    }

arg2中包含列表中选择的名称。使用此名称创建DetailPage(将其传递给DetailPageViewMode,并将其绑定到详细页面中的标签上)。

希望能有所帮助。


谢谢您的建议,不幸的是这会破坏MVVM模式,因为我们正在视图中编写视图逻辑。我想要做的是在类型为内容页的详细页面中显示一个新的内容页。每次从主页面菜单中选择链接时,它都需要加载所需的页面视图。 - Ahhzeee
2
你确定它违反了MVVM模式吗?MVVM只发送消息,由某人接收。我认为MessagingCenter可以替代MVVM框架的其他功能。https://dev59.com/dnA75IYBdhLWcg3wRWyc#3388241 - Alessandro Caliaro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接