2017-03-21 35 views
1

我有一個Xamarin表單應用程序與主詳細信息頁面作爲根視圖。 我正在實施MVVM模式。c#xamarin形式的主詳細信息頁MVVM

我的根頁面加載一個包裹在導航頁面中的詳細信息頁面和一個主頁面,該頁面用於顯示包含指向詳細信息頁面的鏈接的菜單。

主頁面使用列表視圖來保存導航菜單 詳細信息頁面包含主頁面中的所有選定項目,該頁面將顯示新的內容頁面。

我希望我的詳細信息頁面使用自己的ContentPage內容屬性來顯示MasterPage中選定的頁面鏈接。 我想知道這是否可能,如果不是什麼是一些替代品。

這是我的ViewModel爲MasterDetailPage。

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知道任何有關視圖的情況下做到這一點。實現我看起來對我來說至少是可行的。我所關心的是內容頁面內容屬性是否顯示選定的主頁面鏈接?

回答

2

我不知道我是否正確理解你需要什麼。 如果你想打開ContentPage(詳細信息)當選擇SelectedPageLink,我想你可以使用MessagingCenter(希望它遵循MVVM公約...)

看看這個repo

有一個母版其中,在後面的代碼,有這種代碼

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(); 
    } 

它接收到來自它的視圖模型的消息時在列表

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); 
      } 
     } 
    } 
選擇了一個項目210

在arg2中有列表中選擇的名稱。一個DetailPage用此名稱(它被傳遞給DetailPageViewMode並綁定到詳細信息頁面中的標籤)

希望它可以幫助

+0

謝謝你的建議創建可惜這確實打破MVVM模式,因爲我們正在編寫查看視圖中的邏輯。我想要做的是在詳細信息頁面中顯示一個新的內容頁面,該頁面是類型的內容頁面。每次從主頁菜單中選擇一個鏈接時,都需要加載所需的頁面視圖。 – Ahhzeee

+0

你確定它打破了MVVM模式嗎? MVVM只發送某人收到的消息。我認爲MessagingCenter可以替代MVVM框架的其他功能http://stackoverflow.com/a/3388241/4399386 –

+0

您是對的。 – Ahhzeee