.NET MAUI XAML:如何使CollectionView/ListView正确转换和显示空值?

vnzz0bqm  于 2023-11-14  发布在  .NET
关注(0)|答案(1)|浏览(122)

我有一个具有以下属性的ViewModel:

[ObservableProperty]
    ObservableCollection<Agent> agentList;

字符串
此集合数据绑定到CollectionView的ItemSource,我使用AgentToStringConverter来显示Agent对象。如果值为null,此转换器将返回字符串“None”,但是当AgentList包含null值时,“None”不会显示在我的UI上。

<CollectionView ItemsSource="{Binding AgentList}"
                                    SelectionMode="Multiple"
                                    SelectedItems="{Binding QueryAgents}"
                                    IsVisible="{Binding EnableFilters}"
                                    Grid.Row="2"
                                    Grid.Column="3">
                        <CollectionView.ItemTemplate>
                            <DataTemplate>
                                <Label Text="{Binding ., Converter={StaticResource AgentToString}}" />
                            </DataTemplate>
                        </CollectionView.ItemTemplate>
                    </CollectionView>


这是转换器:

internal class AgentToStringConverter : IValueConverter
{
    // Property to get Agents collection from, set in Resource declaration of ProjectDetailsPage.xaml
    public SettingsViewModel SettingsViewModel { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Agent agent)
        {
            var percentage = agent.FeeDecimal * 100;
            return $"{agent.Name}: {percentage:F1}%";
        }

        else if (value == null)
        {
            Debug.WriteLine("NULL VALUE CONVERTED");
            return "None";
        }

        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string stringValue)
        {
            // Split the string into parts assuming it's in the format: "Name: Percentage%"
            var parts = stringValue.Split(':');

            if (parts.Length == 2 && decimal.TryParse(parts[1].Trim().TrimEnd('%'), out decimal percentage))
            {
                var name = parts[0].Trim();
                var feeDecimal = percentage / 100.0m;
                var agent = SettingsViewModel.Agents.First(a => a.Name == name && a.FeeDecimal == feeDecimal);
                return agent;
            }
        }
        return null;
    }
}


为了测试的目的,我也使用了相同的AgentList和AgentToStringConverter为一个Picker和一个ListView。

<Picker ItemsSource="{Binding AgentList}"
                            ItemDisplayBinding="{Binding ., Converter={StaticResource AgentToString}}"
                            Grid.Row="0"
                            Grid.Column="3" />

                    <ListView ItemsSource="{Binding AgentList}"
                              IsVisible="{Binding EnableFilters}"
                              Grid.Row="1"
                              Grid.Column="3">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <ViewCell>
                                    <Label Text="{Binding ., Converter={StaticResource AgentToString}}" />
                                </ViewCell>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>

                    <CollectionView ItemsSource="{Binding AgentList}"
                                    SelectionMode="Multiple"
                                    SelectedItems="{Binding QueryAgents}"
                                    IsVisible="{Binding EnableFilters}"
                                    Grid.Row="2"
                                    Grid.Column="3">
                        <CollectionView.ItemTemplate>
                            <DataTemplate>
                                <Label Text="{Binding ., Converter={StaticResource AgentToString}}" />
                            </DataTemplate>
                        </CollectionView.ItemTemplate>
                    </CollectionView>


UI正确显示“无”作为选择器选项,ListView显示空白,CollectionView完全跳过空值,只显示非空的代理。有什么方法可以使CollectionView或ListView显示空值的“无”吗?
这是我的收藏i.imgur.com/MB0ix7F.png
这就是它如何显示为左侧的选择器选项,以及右侧的CollectionView:i.imgur.com/Qg2aK7j.png
两者都使用相同的AgentList作为ItemSource,使用AgentToStringConverter作为转换器。

moiiocjp

moiiocjp1#

这里没有null:

[ObservableProperty]
ObservableCollection<Agent> agentList;

字符串
ObservableCollection是足够可观察的。不需要创建字段,然后属性。
你可以这样做:

class AgentWrapper {
       Agent agent; //this gets set null every now and then
 }


然后生成ObservableCollection< AgentWrapper >。同样-这里没有空值,只是在里面。
编辑:另一种选择:

public String Property;

public String DisplayProperty
{
      get { return Property == null?"None":Property; }
}


我们将与:

<Label Text="{Binding DisplayProperty}" />

相关问题