Xamarin.Forms xaml视图,导航和绑定

时间:2017-02-12 17:17:46

标签: binding navigation xamarin.forms

我正在尝试设置一个带有标题和状态栏的简单主页,并动态更改中间内容。 我希望尽可能地保持xaml中的视图。 我遇到的问题是绑定。 MainView绑定工作正常。 但是对我的标题,状态和页面浏览的绑定不起作用。 我是否正确设置导航?

这是我的MainView.xaml

var obj = new Form2(1, "test");

My TitleBarView.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>

我的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.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>

我的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.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>

我的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.Page1View">
    <ContentView.Content>
        <StackLayout Orientation="Vertical">
            <Label Text="{Binding Page1Info}"/>
            <Button Text="Go To Page 2" Command="{Binding GoToPage2Command}"/>
        </StackLayout >
    </ContentView.Content>
</ContentView>

等...

我的基本视图模型类,它实现了通知

<?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>

我的MainViewModel.cs

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

我的TitleBarViewModel.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
}

我的StatusBarViewModel.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
}

我的Page1ViewModel.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
}
等等......

我的NavigationController.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
}

为了设置视图,我编辑了MainView.xaml.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");
    }
}

1 个答案:

答案 0 :(得分:0)

我认为Xamarin.Forms提供了您正在寻找的东西。它被称为模板。看看:https://developer.xamarin.com/guides/xamarin-forms/templates/control-templates/introduction/