代码后台访问XAML绑定:Xamarin/UWP页面间传值问询
在Xamarin/UWP中通过后台代码绑定传递页面数据
嘿,这个需求我太熟了!不管是Xamarin还是基于XAML的UWP应用,页面导航时传数据+后台绑定的逻辑其实大同小异,我给你分享两种实用的实现方式,你可以根据自己的场景来选:
方式一:直接设置BindingContext(最省心的方案)
这绝对是日常开发里用得最多的方式,不需要写复杂的绑定代码,直接把你的数据对象当成目标页面的绑定上下文就行,页面上的控件就能直接绑定到对象的属性上。
第一步:先给PaymentPage的XAML准备好绑定控件
比如你要显示订单总额和票务列表,PaymentPage的XAML可以这么写:
<!-- PaymentPage.xaml --> <Label Text="{Binding OrderTotal}" FontSize="Large" /> <ListView ItemsSource="{Binding OrderTotalList}"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text="{Binding TicketName}" Detail="{Binding TicketQuantity}" /> </DataTemplate> </ListView.ItemTemplate> </ListView>
第二步:在源页面里给PaymentPage设置BindingContext
修改你现有的BuyTickets方法就行,加一行代码搞定:
async void BuyTickets(object sender, EventArgs e) { // 先组装好要传递的订单数据 var ticketOrderTotal = new TicketOrder { OrderTotal = lblOrderAmount.Text, OrderTotalList = ticketsPrices.Where(o => o.TicketQuantity > 0).ToList<Ticket>() }; var paymentPage = new PaymentPage(); // 关键一步:把数据对象设为PaymentPage的绑定上下文 paymentPage.BindingContext = ticketOrderTotal; // 导航到支付页面 await Navigation.PushAsync(paymentPage); }
这样一来,PaymentPage上的所有控件都会自动把ticketOrderTotal当成默认绑定源,直接就能拿到数据,省心又高效。
方式二:后台手动创建绑定(适合需要精细控制的场景)
如果你需要更灵活的绑定设置——比如要加转换器、指定绑定模式、或者只给部分控件单独绑定,那可以手动在后台创建Binding对象。
第一步:给PaymentPage的控件加命名
先在PaymentPage的XAML里给需要绑定的控件加上x:Name,方便后台代码引用:
<!-- PaymentPage.xaml --> <Label x:Name="lblOrderTotal" FontSize="Large" /> <ListView x:Name="lvTicketList" />
第二步:两种实现思路
思路A:直接在源页面给目标控件绑定数据
这种方式不用修改PaymentPage的后台代码,直接在跳转前完成绑定:
async void BuyTickets(object sender, EventArgs e) { var ticketOrderTotal = new TicketOrder { OrderTotal = lblOrderAmount.Text, OrderTotalList = ticketsPrices.Where(o => o.TicketQuantity > 0).ToList<Ticket>() }; var paymentPage = new PaymentPage(); // 给订单总额标签创建绑定 var orderTotalBinding = new Binding { Source = ticketOrderTotal, // 绑定源就是我们的订单对象 Path = new PropertyPath(nameof(TicketOrder.OrderTotal)), // 绑定的属性路径 Mode = BindingMode.OneWay // 这里是单向绑定,根据你的需求调整 }; paymentPage.lblOrderTotal.SetBinding(Label.TextProperty, orderTotalBinding); // 给票务列表的ItemsSource创建绑定 var ticketListBinding = new Binding { Source = ticketOrderTotal, Path = new PropertyPath(nameof(TicketOrder.OrderTotalList)) }; paymentPage.lvTicketList.SetBinding(ListView.ItemsSourceProperty, ticketListBinding); // 如果PaymentPage的XAML里没设置ItemTemplate,也可以后台创建 paymentPage.lvTicketList.ItemTemplate = new DataTemplate(() => { var textCell = new TextCell(); textCell.SetBinding(TextCell.TextProperty, nameof(Ticket.TicketName)); textCell.SetBinding(TextCell.DetailProperty, nameof(Ticket.TicketQuantity)); return textCell; }); await Navigation.PushAsync(paymentPage); }
思路B:给PaymentPage定义可绑定属性(更封装)
如果想让PaymentPage的代码更独立、可复用,可以给它定义一个依赖属性来接收数据:
// PaymentPage.xaml.cs public static readonly BindableProperty TicketOrderProperty = BindableProperty.Create( nameof(TicketOrder), typeof(TicketOrder), typeof(PaymentPage), default(TicketOrder)); // 对应的公共属性 public TicketOrder TicketOrder { get => (TicketOrder)GetValue(TicketOrderProperty); set => SetValue(TicketOrderProperty, value); } // 页面加载时完成绑定 protected override void OnAppearing() { base.OnAppearing(); // 把控件绑定到当前页面的TicketOrder属性 lblOrderTotal.SetBinding(Label.TextProperty, new Binding(nameof(TicketOrder.OrderTotal), source: this)); lvTicketList.SetBinding(ListView.ItemsSourceProperty, new Binding(nameof(TicketOrder.OrderTotalList), source: this)); }
然后在源页面里只需要给这个属性赋值就行:
async void BuyTickets(object sender, EventArgs e) { var ticketOrderTotal = new TicketOrder { OrderTotal = lblOrderAmount.Text, OrderTotalList = ticketsPrices.Where(o => o.TicketQuantity > 0).ToList<Ticket>() }; var paymentPage = new PaymentPage(); paymentPage.TicketOrder = ticketOrderTotal; await Navigation.PushAsync(paymentPage); }
额外提醒
- 要是你需要数据变化时UI自动刷新,记得让
TicketOrder类实现INotifyPropertyChanged接口哦,这样属性更新后页面会同步变化。 - 对UWP来说,导航方式可能会换成
Frame.Navigate(typeof(PaymentPage), ticketOrderTotal),然后在PaymentPage的OnNavigatedTo方法里接收参数再设置BindingContext,核心绑定逻辑还是一样的。
内容的提问来源于stack exchange,提问作者smoore4
相关产品推荐
相关产品推荐

