如何通过EventHandler从Rg.Plugins.Popup获取动态值(不使用MessagingCenter)
问题:Xamarin Forms中获取Popup关闭时CollectionView的选中值
我在学习Xamarin Forms,需要在Popup关闭时动态获取其内部CollectionView的选中项。因为代码要在关闭后立即使用选中值,MessagingCenter表现不佳,所以选择用EventHandler实现。但当前遇到问题:调用Popup的PrimaryCommand时,新建的MyGamePopup实例无法获取已打开Popup里更新的ListLangFilter变量值,不知道如何正确获取选中项。
Popup XAML代码
<Grid RowDefinitions="*,50" > <CollectionView Grid.Row="0" x:Name="QuestionLangListView" SelectionMode="Single" SelectionChanged="OnselectLanguageList" > <CollectionView.ItemTemplate> <DataTemplate> <Label Grid.Column="0" TextColor="{StaticResource MySecondColor }" HorizontalTextAlignment="Start" Text="{Binding LanguageKey2}" Style="{StaticResource NormalSizeLabel }"/> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> <StackLayout Grid.Row="1" > <!--关闭Popup的区域--> <StackLayout.GestureRecognizers> <TapGestureRecognizer Command="{Binding PrimaryCommand , Source={Reference ThisPopUpPage}}"/> </StackLayout.GestureRecognizers> </StackLayout> </Grid>
Popup C#代码
string ListLangFilter; void OnselectLanguageList(System.Object sender, Xamarin.Forms.SelectionChangedEventArgs e) { var word = (string)e.CurrentSelection.FirstOrDefault(); // 更新全局变量存储选中值 ListLangFilter = word; }
public event EventHandler<object> ClickEvent; public void OnStartGame() { ClickEvent?.Invoke(this, ListLangFilter); }
调用Popup的代码
await PopupNavigation.Instance.PushAsync(new Mypopup.MyGamePopup(LangQuestionList) { PrimaryCommand = new Command(async () => { await PopupNavigation.Instance.PopAsync(true); Mypopup.MyGamePopup gamepopop = new Mypopup.MyGamePopup(LangQuestionList); gamepopop.ClickEvent += (s,args) => { Console.WriteLine("your arg value is "+ args); }; gamepopop.OnStartGame(); }) });
核心问题
新建的MyGamePopup实例是完全独立的对象,并非当前正在关闭的Popup,因此无法获取用户实际选中的ListLangFilter值。
解决方案
问题的核心是你没有引用当前打开的Popup实例,而是新建了一个无关的对象。下面是两种可行的修复方式:
方式1:提前创建Popup实例并绑定事件
提前实例化Popup对象,直接在PrimaryCommand中使用该实例触发事件或获取选中值:
// 提前创建Popup实例 var gamePopup = new Mypopup.MyGamePopup(LangQuestionList); // 绑定事件监听选中值 gamePopup.ClickEvent += (s, args) => { Console.WriteLine("your arg value is " + args); // 在这里直接执行选中值的后续逻辑 }; // 设置PrimaryCommand,直接使用已创建的实例 gamePopup.PrimaryCommand = new Command(async () => { // 先触发事件传递选中值 gamePopup.OnStartGame(); // 再关闭Popup await PopupNavigation.Instance.PopAsync(true); }); // 弹出Popup await PopupNavigation.Instance.PushAsync(gamePopup);
方式2:在Popup中公开选中值属性(更优雅)
在MyGamePopup类中添加公开属性存储选中值,避免依赖全局变量,直接通过实例获取:
// 在MyGamePopup类中新增公开属性 public string SelectedLanguage { get; private set; } // 修改选中事件方法 void OnselectLanguageList(System.Object sender, Xamarin.Forms.SelectionChangedEventArgs e) { SelectedLanguage = (string)e.CurrentSelection.FirstOrDefault(); } // 可选:修改事件触发方法 public void OnStartGame() { ClickEvent?.Invoke(this, SelectedLanguage); }
此时在调用代码中,无需事件也能直接获取选中值:
var gamePopup = new Mypopup.MyGamePopup(LangQuestionList); gamePopup.PrimaryCommand = new Command(async () => { // 直接获取选中值 var selectedValue = gamePopup.SelectedLanguage; Console.WriteLine("your arg value is " + selectedValue); await PopupNavigation.Instance.PopAsync(true); }); await PopupNavigation.Instance.PushAsync(gamePopup);
内容的提问来源于stack exchange,提问作者hugo
相关产品推荐
相关产品推荐

