You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过EventHandler从Rg.Plugins.Popup获取动态值(不使用MessagingCenter)

问题:Xamarin Forms中获取Popup关闭时CollectionView的选中值

我在学习Xamarin Forms,需要在Popup关闭时动态获取其内部CollectionView的选中项。因为代码要在关闭后立即使用选中值,MessagingCenter表现不佳,所以选择用EventHandler实现。但当前遇到问题:调用Popup的PrimaryCommand时,新建的MyGamePopup实例无法获取已打开Popup里更新的ListLangFilter变量值,不知道如何正确获取选中项。


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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:34:37