【问题标题】:c# xamarin forms master detail page MVVMc# xamarin forms master detail page MVVM
【发布时间】:2017-08-13 17:57:51
【问题描述】:

我有一个 Xamarin Forms 应用程序,其中主详细信息页面作为根视图。 我正在实现 MVVM 模式。

我的根页面加载一个包含在导航页面中的详细信息页面和一个用于显示带有详细页面链接的菜单的母版页面。

母版页使用列表视图保存导航菜单 详细信息页面包含从母版页中选择的所有项目,这将显示一个新的内容页面。

我希望我的详细信息页面使用其自己的 ContentPage 内容属性来显示从 MasterPage 中选择的页面链接。 我想知道这是否可行,如果不可行,还有哪些替代方案。

这是我的 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}}" />**

我要导航到的内容页面是非常简单的内容页面类型。我想在 ViewModel 不了解视图的情况下执行此操作。我的实现至少对我来说是可行的。我担心的是 Content Page Content 属性能否显示选定的母版页链接?

【问题讨论】:

    标签: c# xaml xamarin xamarin.forms


    【解决方案1】:

    我不知道我是否正确理解了您的需求。 如果您想在选择 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 并绑定到 Detail 页面中的 Label)

    希望对你有帮助

    【讨论】:

    • 感谢您的建议,不幸的是,这确实打破了 MVVM 模式,因为我们正在视图中编写视图逻辑。我想要做的是在内容页面类型的详细信息页面中显示一个新的内容页面。每次从主页面菜单中选择一个链接时,它都需要加载所需的页面视图。
    • 你确定它破坏了 MVVM 模式吗? MVVM 仅发送某人收到的消息。我认为 MessagingCenter 替代了 MVVM 框架所做的其他事情stackoverflow.com/a/3388241/4399386
    猜你喜欢
    • 2020-11-05
    • 2018-01-17
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多