c#xamarin构成主要详细信息页面MVVM

时间:2017-03-21 20:43:00

标签: c# xaml xamarin xamarin.forms

我有一个带有Master Detail Page的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

的主页面
 **<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了解视图的情况下做到这一点。我至少对我的实现看起来是可行的..我所关注的是内容页面内容属性是否可以显示所选的母版页链接?

1 个答案:

答案 0 :(得分: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并绑定到详细信息页面中的标签)

希望有所帮助