【问题标题】:Populating a grouped ListView from a list从列表中填充分组的 ListView
【发布时间】:2019-10-03 02:48:06
【问题描述】:

我有一大串通过解析 JSON 文件检索到的对象。现在我将上述列表绑定到ListView,但该列表很笨拙,我想将其分成不同的组以方便使用。我尝试遵循几个不同的指南,但我无法以正确的方式准备我的数据。如果我用一些项目手动初始化我的排序列表之一,它们确实会显示出来,因此代码确实可以运行。

我的分组模型:

public class SortedItem
{
    public string Header { get; set; }
    public List<Item> Items { get; set; }

    public SortedItem(string header)
    {
        Header = header;
    }
}

我的对象模型:

public class Item
{
    public string item { get; set; }
    //public int icon { get; set; }

    private string ico;
    public string icon
    {
        get { return ico; }
        set { ico = "Icons/" + value + ".png"; }
    }

    public int id { get; set; }
    public string slot { get; set; }
    public string scrip { get; set; }
    public Reduce reduce { get; set; }
    public int lvl { get; set; }
    public string zone { get; set; }
    public int time { get; set; }
}

现在我的 XAML 如下:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
     x:Class="Eorzea_Gatherer.Pages.NodesPage"
     xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core" 
     ios:Page.UseSafeArea="true"
     BackgroundColor="#F4F4F4">
<!--https://xamarinhelp.com/safeareainsets-xamarin-forms-ios/-->
<ListView x:Name="nodesListView"
      IsGroupingEnabled="True"
      GroupDisplayBinding="{Binding Header}"
      HasUnevenRows="True"
      BackgroundColor="#F4F4F4"
      Margin="30, 30, 30, 0">
<ListView.ItemTemplate>
    <DataTemplate>
        <ViewCell>
            <Grid Padding="0, 5">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Image Source="{Binding icon}"
                       HeightRequest="50"
                       WidthRequest="50"
                       Grid.Column="0"/>
                <StackLayout Grid.Column="1">
                    <Label Text="{Binding item}"
                           TextColor="#171717"
                           FontSize="13"
                           FontFamily="SegoeUI"/>
                    <!--https://forums.xamarin.com/discussion/97996/binding-more-than-one-property-in-listview-->
                    <Label TextColor="#171717"
                           FontSize="12"
                           FontFamily="SegoeUI">
                        <Label.FormattedText>
                            <FormattedString>
                                <Span Text="{Binding zone}"/>
                                <Span Text=" - "/>
                                <Span Text="{Binding slot}"/>
                            </FormattedString>
                        </Label.FormattedText>
                    </Label>
                    <Label TextColor="#171717"
                           FontSize="12"
                           FontFamily="SegoeUI">
                        <Label.FormattedText>
                            <FormattedString>
                                <Span Text="{Binding time}"/>
                                <Span Text=" - "/>
                                <Span Text="00:00 AM"/>
                            </FormattedString>
                        </Label.FormattedText>
                    </Label>
                </StackLayout>
            </Grid>
        </ViewCell>
    </DataTemplate>
</ListView.ItemTemplate>
</ListView>

我用来检索列表并将其作为源绑定到 ListView 的函数:

public static List<SortedItem> GetSortedItems()
{
    List<Item> items = GetItems();

    List<SortedItem> sortedItems = new List<SortedItem>()
    {
        new SortedItem("50")
        {
           Items = items.Where(x => x.lvl == 50).ToList()
        },
        new SortedItem("55"),
        new SortedItem("60"),
        new SortedItem("65"),
        new SortedItem("70")
    };

    return sortedItems;
}

使用我的代码,我可以在我的 ListView 中看到不同的组(50、55、...),但没有其他任何内容弹出。我确定我的问题是获取我的对象列表并以适当的方式拆分它,但我很难过。令我困惑的是,在调试过程中,将鼠标悬停在生成的 sortedItems 上时,我看到我的第一组确实包含它需要的对象,但它们仍然没有出现在视图中。

【问题讨论】:

    标签: c# listview xamarin.forms listviewgroup


    【解决方案1】:

    我可能遗漏了一些东西,但是您将List&lt;item&gt; Items 绑定在哪里?我认为您的 ListView 缺少 ItemSource="{Binding Items}" 之类的东西,从那里看来,您的 ViewCell 绑定正常,应该可以按预期工作。

    【讨论】:

    • 我没有添加它,因为它在我的视图构造函数后面的代码中,我认为它是多余的。不过谢谢!
    【解决方案2】:

    你应该让你的分组模型继承自ObservableCollection

    public class SortedItem : ObservableCollection<Item>
    {
        public string Header { get; set; }
    
        public SortedItem(List<Item> list) : base(list)
        {
    
        }
    }
    

    然后按如下方式排序:

    public static List<SortedItem> GetSortedItems()
    {
        List<Item> items = GetItems();
    
        List<SortedItem> sortedItems = new List<SortedItem>()
        {
            new SortedItem(items.Where(x => x.lvl == 50).ToList())
            {
                Header = "50"
            },
            new SortedItem(items.Where(x => x.lvl == 55).ToList())
            {
                Header = "55"
            },
            new SortedItem(items.Where(x => x.lvl == 60).ToList())
            {
                Header = "60"
            },
            new SortedItem(items.Where(x => x.lvl == 65).ToList())
            {
                Header = "65"
            },
            new SortedItem(items.Where(x => x.lvl == 70).ToList())
            {
                Header = "70"
            }
        };
    
        return sortedItems;
    }
    

    此外,尝试在您的模型中实现INotifyPropertyChanged 接口。否则,如果您在运行时更改了模型的属性,UI 将不会收到通知。

    【讨论】:

      【解决方案3】:

      试试这个,从James Montemagno偷来的

      public class Grouping<K, T> : ObservableCollection<T>
      {
        public K Key { get; private set; }
      
        public Grouping(K key, IEnumerable<T> items)
        {
            Key = key;
            foreach (var item in items)
              this.Items.Add(item);
        }
      }
      
      var sorted = from item in Items
                   orderby item.lvl
                   group item by item.lvl into itemGroup
                   select new Grouping<int, Item>(itemGroup.Key, itemGroup);
      
      //create a new collection of groups
      ItemsGrouped = new ObservableCollection<Grouping<int, Item>>(sorted);
      

      然后在你的 XAML 中

      GroupDisplayBinding="{Binding Key}"
      

      【讨论】:

      • 谢谢!您和@Land Lu 的解决方案都运行良好,但我选择集成他的解决方案,因为它更容易添加到我的代码中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2015-09-14
      • 1970-01-01
      • 2013-12-19
      • 1970-01-01
      • 1970-01-01
      • 2013-08-12
      相关资源
      最近更新 更多