2017-02-12 56 views
0

我想設置一個簡單的主頁與標題和狀態欄,並動態地改變中間內容。 我想盡可能保留xaml中的視圖。 我遇到的問題是綁定。 MainView綁定工作正常。 但我的標題,狀態和頁面視圖的綁定不起作用。 我能正確設置導航嗎?Xamarin.Forms xaml的意見,導航和綁定

這裏是我的MainView.xaml

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      xmlns:local="clr-namespace:MyApp.Views" 
      x:Class="MyApp.Views.MainView"> 
    <ContentPage.Content> 
     <Grid HorizontalOptions="FillAndExpand"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="*"/> 
       <RowDefinition Height="Auto"/> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto"/> 
       <ColumnDefinition Width="*"/> 
       <ColumnDefinition Width="Auto"/> 
      </Grid.ColumnDefinitions> 
      <Grid.Children>     
       <Button Grid.Row="0" Grid.Column="0" 
         Text="Show Menu" 
         Command="{Binding ShowMenuCommand}" 
         BackgroundColor="Yellow" /> 
       <local:TitleBarView Grid.Row="0" Grid.Column="1"/> 
       <Button Grid.Row="0" Grid.Column="2" 
         Text="Show Options" 
         Command="{Binding ShowOptionsCommand}" 
         BackgroundColor="Lime"/> 
       <ContentView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" 
          x:Name="MainContent" />     
       <local:StatusBarView Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3"/> 
      </Grid.Children> 
     </Grid> 
    </ContentPage.Content> 
</ContentPage> 

我TitleBarView.xaml

<?xml version="1.0" encoding="UTF-8"?> 
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="MyApp.Views.TitleBarView"> 
    <ContentView.Content> 
     <StackLayout Orientation="Horizontal" BackgroundColor="Blue"> 
      <Label Text="TitleInfo1: " TextColor="White"/> 
      <Label Text="{Binding TitleInfo1}" TextColor="White"/> 
      <Label Text="TitleInfo2: " TextColor="White"/> 
      <Label Text="{Binding TitleInfo2}" TextColor="White"/> 
     </StackLayout> 
    </ContentView.Content> 
</ContentView> 

我StatusBarView.xaml

<?xml version="1.0" encoding="utf-8" ?> 
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="MyApp.Views.StatusBarView"> 
    <ContentView.Content> 
     <StackLayout Orientation="Horizontal" BackgroundColor="Green"> 
      <Label Text="StatusInfo1: " TextColor="White"/> 
      <Label Text="{Binding StatusInfo1}" TextColor="White"/> 
      <Label Text="StatusInfo2: " TextColor="White"/> 
      <Label Text="{Binding StatusInfo2}" TextColor="White"/> 
     </StackLayout> 
    </ContentView.Content> 
</ContentView> 

我Page1View.xaml

<?xml version="1.0" encoding="UTF-8"?> 
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="MyApp.Views.Page1View"> 
    <ContentView.Content> 
     <StackLayout Orientation="Vertical"> 
      <Label Text="{Binding Page1Info}"/> 
      <Button Text="Go To Page 2" Command="{Binding GoToPage2Command}"/> 
     </StackLayout > 
    </ContentView.Content> 
</ContentView> 

我Page2View.xaml

<?xml version="1.0" encoding="UTF-8"?> 
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="MyApp.Views.Page2View"> 
    <ContentView.Content> 
     <StackLayout Orientation="Vertical"> 
      <Label Text="{Binding Page2Info}"/> 
      <Button Text="Go To Page 1" Command="{Binding GoToPage1Command}"/> 
      <Button Text="Go To Page 3" Command="{Binding GoToPage3Command}"/> 
     </StackLayout > 
    </ContentView.Content> 
</ContentView> 

等等實現通知

public class ViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, 
       new PropertyChangedEventArgs(propertyName)); 
    } 
} 

我MainViewModel.cs

class MainViewModel : ViewModel 
{ 
    private const string TAG = "MainViewModel"; 

    public MainViewModel() 
    { 
     Logger.mt(TAG, "MainViewModel()"); 
    } 

    #region ShowMenuCommand 
    private Command _showMenuCommand; 
    public ICommand ShowMenuCommand 
    { 
     get 
     { 
      if (_showMenuCommand == null) 
       _showMenuCommand = new Command(param => this.showMenuClick()); 
      return _showMenuCommand; 
     } 
    } 

    public void showMenuClick() 
    { 
     Logger.ui(TAG, "showMenuClick()"); 
     //ToDo: show main menu 
    } 
    #endregion 

    #region ShowOptionsCommand 
    private Command _showOptionsCommand; 
    public ICommand ShowOptionsCommand 
    { 
     get 
     { 
      if (_showOptionsCommand == null) 
       _showOptionsCommand = new Command(param => this.showOptionsClicked()); 
      return _showOptionsCommand; 
     } 
    } 

    public void showOptionsClicked() 
    { 
     Logger.ui(TAG, "showOptionsClicked()"); 
     //ToDo: show options menu 
    } 
    #endregion 
} 

我TitleBarViewModel

我的基本視圖模型類.cs

class TitleBarViewModel : ViewModel 
{ 
    private const string TAG = "TitleBarViewModel"; 

    public TitleBarViewModel() 
    { 
     Logger.mt(TAG, "TitleBarViewModel()"); 
    } 

    #region TitleInfo1 
    private string _titleInfo1 = "This is title info 1"; 
    public string TitleInfo1 
    { 
     get { return _titleInfo1; } 
     set 
     { 
      if (!value.Equals(_titleInfo1)) 
      { 
       _titleInfo1 = value; 
       OnPropertyChanged("TitleInfo1"); 
      } 
     } 
    } 
    #endregion 

    #region TitleInfo2 
    private int _titleInfo2 = 14; 
    public int TitleInfo2 
    { 
     get { return _titleInfo2; } 
     set 
     { 
      if (value != _titleInfo2) 
      { 
       _titleInfo2 = value; 
       OnPropertyChanged("TitleInfo2"); 
      } 
     } 
    } 
    #endregion 
} 

我StatusBarViewModel.cs

class StatusBarViewModel : ViewModel 
{ 
    private const string TAG = "StatusBarViewModel"; 

    public StatusBarViewModel() 
    { 
     Logger.mt(TAG, "StatusBarViewModel()"); 
    } 

    #region StatusInfo1 
    private string _statusInfo1 = "This is Status Info 1"; 
    public string StatusInfo1 
    { 
     get { return _statusInfo1; } 
     set 
     { 
      if (!value.Equals(_statusInfo1)) 
      { 
       _statusInfo1 = value; 
       OnPropertyChanged("StatusInfo1"); 
      } 
     } 
    } 
    #endregion 

    #region StatusInfo2 
    private string _statusInfo2 = "This is Status Info 2"; 
    public string StatusInfo2 
    { 
     get { return _statusInfo2; } 
     set 
     { 
      if (!value.Equals(_statusInfo2)) 
      { 
       _statusInfo2 = value; 
       OnPropertyChanged("StatusInfo2"); 
      } 
     } 
    } 
    #endregion 
} 

我Page1ViewModel.cs

class Page1ViewModel : ViewModel 
{ 
    private const string TAG = "Page1ViewModel"; 

    public Page1ViewModel() 
    { 
     Logger.mt(TAG, "Page1ViewModel()"); 
    } 

    #region Page1Info 
    private string _page1Info = "This is Page 1 Info"; 
    public string Page1Info 
    { 
     get { return _page1Info; } 
     set 
     { 
      if (!value.Equals(_page1Info)) 
      { 
       _page1Info = value; 
       OnPropertyChanged("Page1Info"); 
      } 
     } 
    } 
    #endregion 

    #region Go To Page 2 
    private Command _goToPage2Command; 
    public ICommand GoToPage2Command 
    { 
     get 
     { 
      if (_goToPage2Command == null) 
       _goToPage2Command = new Command(param => this.goToPage2Clicked()); 
      return _goToPage2Command; 
     } 
    } 

    public void goToPage2Clicked() 
    { 
     Logger.ui(TAG, "goToPage2Clicked()"); 
     NavigationController.setContentPage(typeof(Page2View)); 
    } 
    #endregion 
} 

等等

我NavigationController.cs

public class NavigationController 
{ 
    private const string TAG = "NavigationController"; 

    static MainView mainView; 
    static MainViewModel mainViewModel; 

    static TitleBarView titleBarView; 
    static TitleBarViewModel titleBarViewModel; 

    static StatusBarView statusBarView; 
    static StatusBarViewModel statusBarViewModel; 

    static List<ContentView> viewList = new List<ContentView>(); 
    static ContentView currentView; 

    public static void Initialize() 
    { 
     Logger.mt(TAG, "Initialize()"); 

     mainView = new MainView(); 
     mainViewModel = new MainViewModel(); 
     mainView.BindingContext = mainViewModel; 

     titleBarView = new TitleBarView(); 
     titleBarViewModel = new TitleBarViewModel(); 
     titleBarView.BindingContext = titleBarViewModel; 

     statusBarView = new StatusBarView(); 
     statusBarViewModel = new StatusBarViewModel(); 
     statusBarView.BindingContext = statusBarViewModel; 

     Page1View view1 = new Page1View(); 
     Page1ViewModel viewModel1 = new Page1ViewModel(); 
     view1.BindingContext = viewModel1; 
     viewList.Add(view1); 

     Page2View view2 = new Page2View(); 
     Page2ViewModel viewModel2 = new Page2ViewModel(); 
     view2.BindingContext = viewModel2; 
     viewList.Add(view2); 

     Page3View view3 = new Page3View(); 
     Page3ViewModel viewModel3 = new Page3ViewModel(); 
     view3.BindingContext = viewModel3; 
     viewList.Add(view3); 

     mainView.setMainContent(view1); 
     currentView = view1; 
    } 

    public static Page getMainPage() 
    { 
     Logger.mt(TAG, "getMainPage()"); 
     return mainView; 
    } 

    public static void setContentPage(Type type) 
    { 
     Logger.mt(TAG, "setContentPage(" + type.ToString() + ")"); 
     foreach (ContentView cv in viewList) 
     { 
      if (cv.GetType() == type) 
      { 
       if (cv != currentView) 
       { 
        mainView.setMainContent(cv); 
        currentView = cv; 
        Logger.mt(TAG, "setContentPage() FOUND"); 
        return; 
       } 
      } 
     } 
     Logger.mt(TAG, "setContentPage() NOT FOUND"); 
    } 
} 

,並設置來看,我編輯的MainView.xaml.cs

public partial class MainView : ContentPage 
{ 
    private const string TAG = "MainView"; 

    public MainView() 
    { 
     Logger.mt(TAG, "MainView()"); 
     InitializeComponent(); 
    } 

    public bool setMainContent(ContentView view) 
    { 
     Logger.mt(TAG, "setMainContent()"); 
     MainContent.Content = view.Content; 
     return true; 
    } 
} 

回答