我正在使用带有 Prism MVVM 框架的 Xamarin Forms。
我在做嵌套 TabbedPage 时遇到问题。
例如我有 TabbedPage1。
然后我添加 TabbedPage2 和 Page99 作为 TabbedPage1 的子级。
然后我将 Page1 和 Page2 添加为 TabbedPage2 的子项。
但是结果是 Page1 和 Page2 变成了空白 Page 并且 Page1 和 Page2 的标题变成了 TabbedPage2 的标题
我正在使用 Xamarin 3.1.0.697729 和 Prism 7.0.0.396
这是截图
这是复制完整项目或github 。我举了一个例子,说明使用 mvvm 和不使用 mvvm 的区别。
这是一些源代码
TabbedPage1.xaml
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AssetKita.Views.TabbedPage1"
Title="{Binding Title}"
xmlns:Existing_Page="clr-namespace:AssetKita.Views">
<ContentPage Title="Tab 1" />
<ContentPage Title="Tab 2" />
<ContentPage Title="Tab 3" />
<Existing_Page:TabbedPage2/>
<ContentPage Title="Tab 5" />
</TabbedPage>
TabbedPage1.xaml.cs
namespace AssetKita.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TabbedPage1 : Xamarin.Forms.TabbedPage
{
public TabbedPage1 ()
{
InitializeComponent();
On<Xamarin.Forms.PlatformConfiguration.Android>().SetToolbarPlacement(Xamarin.Forms.PlatformConfiguration.AndroidSpecific.ToolbarPlacement.Bottom);
On<Xamarin.Forms.PlatformConfiguration.Android>().SetBarSelectedItemColor((Color)App.Current.Resources["PrimaryGreenColor"]);
}
}
}
TabbedPage2.xaml
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AssetKita.Views.TabbedPage2"
xmlns:Existing_Page="clr-namespace:AssetKita.Views"
Title="{Binding Title}">
<Existing_Page:Page1/>
<Existing_Page:Page2/>
</TabbedPage>
Page1.xaml 和 Page2.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"
x:Class="AssetKita.Views.ItemList_Invest_Page"
Title="{Binding Title}">
<ListView ItemsSource="{Binding PostItems, Mode=TwoWay}"
SeparatorVisibility="None"
CachingStrategy="RecycleElement"
HasUnevenRows="True"
x:Name="listview_item">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame Padding="0" Margin="10">
<Frame.HasShadow>
<OnPlatform x:TypeArguments="x:Boolean" iOS="True" Android="True">
</OnPlatform>
</Frame.HasShadow>
<Frame.BorderColor>
<OnPlatform x:TypeArguments="Color" iOS="Transparent" Android="Default"/>
</Frame.BorderColor>
<Frame.BackgroundColor>
<OnPlatform x:TypeArguments="Color" iOS="Transparent" Android="Default"/>
</Frame.BackgroundColor>
<Grid HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Padding="10"
RowSpacing="5"
ColumnSpacing="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="5"
Margin="0,0,10,0"
Source="{Binding IMAGE_LINK}"
Aspect="AspectFill"/>
<Label Text="{Binding NAME}"
FontSize="Medium"
FontAttributes="Bold"
Grid.Column="1"
Grid.Row="0"
Grid.ColumnSpan="4"/>
<Label Text="Kategori"
Grid.Column="1"
Grid.Row="1"/>
<Label Text="Bunga"
Grid.Column="1"
Grid.Row="2"/>
<Label Text="Durasi"
Grid.Column="1"
Grid.Row="3"/>
<Label Text=":"
Grid.Column="2"
Grid.Row="1"/>
<Label Text=":"
Grid.Column="2"
Grid.Row="2"/>
<Label Text=":"
Grid.Column="2"
Grid.Row="3"/>
<Label Text="{Binding CATEGORY}"
Grid.Column="3"
Grid.Row="1"/>
<Label Text="{Binding ASKING_INTEREST_RATE}"
Grid.Column="3"
Grid.Row="2"/>
<Label Text="{Binding DURATION}"
Grid.Column="3"
Grid.Row="3"/>
<Label x:Name="label_price"
FontSize="Medium"
TextColor="#FF6F00"
Grid.Column="1"
Grid.Row="4"
Grid.ColumnSpan="4"/>
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Page1ViewModel.cs 和 Page2ViewModel.cs
namespace AssetKita.ViewModels
{
class Page1ViewModel : ViewModelChild
{
private List<PostItem> postItems = new List<PostItem>()
{
new PostItem
{
NAME = "Emas 24 Karat",
ASKING_INTEREST_RATE = "2%",
ASKING_PRICE = "1.000.000",
CATEGORY = "Emas",
DESCRIPTION = "Berat 3 gram",
DURATION = "30 hari",
IMAGE_LINK = "https://fm.cnbc.com/applications/cnbc.com/resources/img/editorial/2017/10/02/104748034-GettyImages-90075023.530x298.jpg?v=1506995840"
},
new PostItem
{
NAME = "Redmi Note 5",
ASKING_INTEREST_RATE = "2%",
ASKING_PRICE = "2.000.000",
CATEGORY = "Smartphone",
DESCRIPTION = "Mulus Like New",
DURATION = "30 hari",
IMAGE_LINK = "http://st1.bgr.in/wp-content/uploads/2018/02/Xiaomi-Redmi-Note-5-Front.jpg"
},
new PostItem
{
NAME = "MacBook Pro 15 inch 2018",
ASKING_INTEREST_RATE = "2%",
ASKING_PRICE = "20.000.000",
CATEGORY = "Elektronik",
DESCRIPTION = "Mulus Like New",
DURATION = "30 hari",
IMAGE_LINK = "https://www.insightmac.com/wp-content/uploads/2018/07/26826-38847-2018-MacBook-Pro-15-inch-l.jpg"
},
};
public List<PostItem> PostItems
{
get { return postItems; }
set { SetProperty(ref postItems, value); }
}
public ItemList_Invest_ViewModel(INavigationService navigationService,
IPageDialogService pageDialog)
{
Title = "INVEST";
}
}
}
ViewModelChild.cs
namespace AssetKita.ViewModels
{
public class ViewModelChild : ViewModelBase, IActiveAware
{
private string _message;
public string Message
{
get { return _message; }
set { SetProperty(ref _message, value); }
}
private bool _isActive;
public bool IsActive
{
get { return _isActive; }
set { SetProperty(ref _isActive, value, () => System.Diagnostics.Debug.WriteLine($"{Title} IsActive Changed: {value}")); }
}
public event EventHandler IsActiveChanged;
public ViewModelChild()
{
IsActiveChanged += (sender, e) => System.Diagnostics.Debug.WriteLine($"{Title} IsActive: {IsActive}");
}
public override void OnNavigatingTo(NavigationParameters parameters)
{
System.Diagnostics.Debug.WriteLine($"{Title} is executing OnNavigatingTo");
var message = parameters.GetValue<string>("message");
Message = $"{Title} Initialized by OnNavigatingTo: {message}";
}
public override void Destroy()
{
System.Diagnostics.Debug.WriteLine($"{Title} is being Destroyed!");
}
}
}
ViewModelBase.cs
namespace AssetKita.ViewModels
{
public class ViewModelBase : BindableBase, INavigationAware, IDestructible
{
protected INavigationService NavigationService { get; private set; }
private string _title;
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public virtual void OnNavigatedFrom(NavigationParameters parameters)
{
}
public virtual void OnNavigatedTo(NavigationParameters parameters)
{
}
public virtual void OnNavigatingTo(NavigationParameters parameters)
{
}
public virtual void Destroy()
{
}
}
}
PostItem.cs
namespace AssetKita.Models
{
class PostItem
{
public string IMAGE_LINK { get; set; }
public string NAME { get; set; }
public string WEIGHT { get; set; }
public string CATEGORY { get; set; }
public string ASKING_PRICE { get; set; }
public string ASKING_INTEREST_RATE { get; set; }
public string DURATION { get; set; }
public string DESCRIPTION { get; set; }
public Owner owner { get; set; }
public string OWNER_LOCATION
{
get { return owner.LOCATION; }
set { owner.LOCATION = value; }
}
}
}
所有者.cs
namespace AssetKita.Models
{
class PostItem
{
public string IMAGE_LINK { get; set; }
public string NAME { get; set; }
public string WEIGHT { get; set; }
public string CATEGORY { get; set; }
public string ASKING_PRICE { get; set; }
public string ASKING_INTEREST_RATE { get; set; }
public string DURATION { get; set; }
public string DESCRIPTION { get; set; }
public Owner owner { get; set; }
public string OWNER_LOCATION
{
get { return owner.LOCATION; }
set { owner.LOCATION = value; }
}
}
}
应用程序.xaml.cs
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace AssetKita
{
public partial class App : PrismApplication
{
public App() : this(null) { }
public App(IPlatformInitializer initializer) : base(initializer) { }
protected override async void OnInitialized()
{
InitializeComponent();
await NavigationService.NavigateAsync("NavigationPage/TabbedPage1");
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<NavigationPage>();
containerRegistry.RegisterForNavigation<TabbedPage1>();
containerRegistry.RegisterForNavigation<TabbedPage2>();
containerRegistry.RegisterForNavigation<Page1>();
containerRegistry.RegisterForNavigation<Page2>();
}
}
}