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

MAUI中如何在选择后动态修改Picker选项显示内容?

解决方案:利用MAUI Picker的双模板实现差异化显示

要实现Picker下拉时显示「描述+日期区间」、选中后仅显示「描述」的效果,最优雅的方式是利用MAUI Picker原生支持的ItemTemplate(下拉列表项模板)和ContentTemplate(选中后显示模板),无需依赖转换器做复杂判断,代码更清晰易维护。

步骤1:修改XAML中的Picker配置

移除原有的ItemDisplayBinding,分别定义下拉项和选中后的显示模板:

<Picker
    x:Name="pickerTravelOrder"
    Style="{StaticResource pickerStyle}"
    HorizontalTextAlignment="Center"
    FontSize="12"
    SelectedIndex="0"
    Title="{x:Static res:AppRes.TravelOrder}"
    SelectedItem="{Binding SelectedTravelOrder}"
    ItemsSource="{Binding TravelOrders}">
    <!-- 下拉列表项:显示完整的描述+日期区间 -->
    <Picker.ItemTemplate>
        <DataTemplate>
            <Label>
                <Label.FormattedText>
                    <FormattedString>
                        <Span Text="{Binding Description}" />
                        <Span Text=" (" />
                        <Span Text="{Binding StartDate, StringFormat='{0:d}'}" />
                        <Span Text=" - " />
                        <Span Text="{Binding EndDate, StringFormat='{0:d}'}" />
                        <Span Text=")" />
                    </FormattedString>
                </Label.FormattedText>
            </Label>
        </DataTemplate>
    </Picker.ItemTemplate>
    <!-- 选中后显示:仅展示描述内容 -->
    <Picker.ContentTemplate>
        <DataTemplate>
            <Label Text="{Binding Description}" />
        </DataTemplate>
    </Picker.ContentTemplate>
</Picker>

步骤2:调整ViewModel逻辑

在ViewModel中新增SelectedTravelOrder属性,用于绑定Picker的选中项,同时同步差旅订单ID和日期到对应的绑定字段:

private TravelOrder _selectedTravelOrder;
public TravelOrder SelectedTravelOrder
{
    get => _selectedTravelOrder;
    set
    {
        if (_selectedTravelOrder != value)
        {
            _selectedTravelOrder = value;
            OnPropertyChanged();
            
            if (value != null)
            {
                // 同步差旅订单ID到ExpenseReport
                ExpenseReport.TravelOrderID = value.ID;
                // 同步日期到下方DatePicker的绑定属性
                SelectedStartDate = value.StartDate;
                SelectedEndDate = value.EndDate;
            }
        }
    }
}

// 对应下方DatePicker的绑定属性
public DateTime SelectedStartDate { get; set; }
public DateTime SelectedEndDate { get; set; }

替代方案:基于转换器+状态判断(兼容旧版本)

如果你的项目使用的MAUI版本不支持ContentTemplate,可以通过「转换器+Picker状态标记」实现:

  1. 在ViewModel中添加IsPickerOpen属性,标记Picker是否处于展开状态:
private bool _isPickerOpen;
public bool IsPickerOpen
{
    get => _isPickerOpen;
    set => SetProperty(ref _isPickerOpen, value);
}
  1. 修改XAML的ItemDisplayBinding,传递IsPickerOpen作为转换器参数:
ItemDisplayBinding="{Binding ., Converter={StaticResource TravelOrderPickerConverter}, ConverterParameter={Binding IsPickerOpen, Source={x:Reference YourPageName}}}"
  1. 更新转换器逻辑,根据状态切换显示内容:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    TravelOrder model = value as TravelOrder;
    if (model == null) return string.Empty;

    bool isPickerOpen = parameter is bool b && b;

    if (model.Description == AppRes.None)
    {
        return $"--- {model.Description} ---";
    }

    return isPickerOpen 
        ? $"{model.Description} ({model.StartDate.ToShortDateString()} - {model.EndDate.ToShortDateString()})" 
        : model.Description;
}
  1. 在页面的Picker焦点事件中更新状态:
private void pickerTravelOrder_Focused(object sender, FocusEventArgs e)
{
    ViewModel.IsPickerOpen = true;
}

private void pickerTravelOrder_Unfocused(object sender, FocusEventArgs e)
{
    ViewModel.IsPickerOpen = false;
    ViewModel.OnPropertyChanged(nameof(ViewModel.SelectedTravelOrder));
}

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 08:32:29