c# - 在 XMAL/C# 中的页面之间传递“间接”对象
问题描述
我已经定义了一个 Player 对象,如下所示:
public class Player
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string PlayerName { get; set; }
public DateTime JoinDate { get; set; }
public int TotalMatchesWon { get; set; }
public int TotalMatchesLost { get; set; }
public float WinPercentage { get; set; }
public int Rank { get; set; }
}
我将玩家存储在 SQLite 数据库中。我正在为 Xamarin 中的 android 应用程序实现以下页面:
名册 -> 名册详情 -> 编辑球员
这些页面具有以下功能:
名册: 1. Roster.xmal 包含一个球员列表视图(名册),由 Roster.xmal.cs 中的以下函数填充。
protected override async void OnAppearing()
{
base.OnAppearing();
listView.ItemsSource = await App.Database.GetPlayersAsync();
}
- 将新玩家添加到名册。这将使用 Roster.xmal.cs 文件中的以下代码调用带有空字段的 Edit Player 页面。
async void OnPlayerAddedClicked(object send, EventArgs e)
{
await Navigation.PushAsync(new RosterEntryPage
{
BindingContext = new Player()
});
}
- 您可以从列表中选择一个播放器。这需要 SelectedItem 并将 Player 发送到 PlayerDetailPage(也在 Roster.xmal.cs 中)
async void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem != null)
{
await Navigation.PushAsync(new PlayerDetailPage
{
BindingContext = e.SelectedItem as Player
});
}
}
名单详细信息: 1. 显示从 OnListViewItemSelected() 函数传递给它的 Player 对象。页面上没有指定它具有 Player 的代码,但我可以像这样引用 RosterDetails.xmal 文件中的 Player 字段(这就是我称之为“间接”对象的原因):
<Label Grid.Column="2"
Text="{Binding PlayerName}"
FontSize="18"
FontAttributes="Bold" />
- 用户可以单击按钮来编辑播放器。这会再次调用 RosterEntryPage(就像添加一个新玩家一样),但这一次它传递了它已经拥有的玩家。这是坏掉的部分。如果我直接从 Roster.xmal 调用编辑页面,我可以预先填充所有空白字段(但那只是 PlayerName)并更新 SQLite 记录。我想将 RosterDetail.xmal 使用的间接对象传递给编辑页面来做同样的事情。
这是 RosterDetail.xmal.cs:
public partial class PlayerDetailPage : ContentPage
{
public PlayerDetailPage()
{
InitializeComponent();
}
async void OnEditPlayerButtonClicked(object send, EventArgs e)
{
await floatingButtonEdit.ScaleTo(1.5, 500);
await floatingButtonEdit.ScaleTo(0, 500, Easing.SpringOut);
await Navigation.PushAsync(new RosterEntryPage
{
BindingContext = new Player()
});
}
}
我知道问题在于 BindingContext = new Player(),但我不知道用什么替换它。我尝试了各种方法,例如 BindingContext = e.Player ,但这给出了 e.Player 无效的错误。我还尝试更改函数参数以匹配 OnListViewItemSelected() 以便它是 OnEditPlayerButtonClicked(object sender, SelectedItemChangedEventArgs e) 但这会导致应用程序崩溃。
编辑 这是您进行数据输入以添加新播放器或编辑现有播放器的页面的 xmal。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Foosball.RosterEntryPage"
Title="Roster Entry">
<StackLayout Margin="20">
<Editor Placeholder="Enter player name"
Text="{Binding PlayerName}"
HeightRequest="50" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Text="Save"
Clicked="OnRosterEntrySaveButtonClicked"
Grid.Row="1" />
<Button Text="Delete"
Clicked="OnRosterEntryDeleteButtonClicked"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
</StackLayout>
</ContentPage>
这是关联的 .cs 文件
public partial class RosterEntryPage : ContentPage
{
public RosterEntryPage()
{
InitializeComponent();
}
public RosterEntryPage(Player newPlayer)
{
InitializeComponent();
}
async void OnRosterEntrySaveButtonClicked(object sender, EventArgs e)
{
var player = (Player)BindingContext;
player.JoinDate = DateTime.UtcNow;
await App.Database.SavePlayerAsync(player);
await Navigation.PopAsync();
}
async void OnRosterEntryDeleteButtonClicked(object sender, EventArgs e)
{
var player = (Player)BindingContext;
await App.Database.DeletePlayerAsync(player);
await Navigation.PopAsync();
}
}
解决方案
BindingContext
而不是在导航到页面之前设置页面,而是通过构造函数传递数据并让页面设置它自己的BindingContext
Player ViewModel { get; set; }
public PlayerDetailPage(Player player)
{
InitializeComponent();
this.BindingContext = ViewModel = player;
}
然后
async void OnEditPlayerButtonClicked(object send, EventArgs e)
{
await floatingButtonEdit.ScaleTo(1.5, 500);
await floatingButtonEdit.ScaleTo(0, 500, Easing.SpringOut);
await Navigation.PushAsync(new RosterEntryPage(ViewModel));
}
推荐阅读
- react-native - React Native 中的 PanResponder 和动画问题
- whatsapp - Whatsapp 发送文本 URL(移动和网络)中的 `text` 参数的最大字符限制是多少?
- nanoframework - Visual Studio 在创建新类时崩溃
- python-3.x - 如何使文件不可编辑?
- excel - Excel - 乘数效应/循环
- java - StringEscapeUtils中的unescapeJava和unescapeJson有什么区别
- javascript - 在更改时对具有相同类的所有输入求和 - JavaScript
- javascript - 如何在 JavaScript/Vue v-for 循环中从对象本身获取 JSON 对象的密钥?
- python - Pandas 按一列分组,只保留列包含一组所有值的组
- jboss - java.lang.NoClassDefFoundError:Keycloak 适配器中的 java/util/logging/Logger