【问题标题】:Xamarin forms:Listview grouping issueXamarin 表单:Listview 分组问题
【发布时间】:2020-02-07 17:16:26
【问题描述】:

我正在尝试为我的以下 JSON 数据实现列表视图分组。

JSON 示例:

{ 
   "cbrainBibleBooksHB":[ { 
        "book":"2 John",
         "cbrainBibleTOList":[ 
            { 
               "bookName":"2 John",
               "chapter":"1",
               "pageUrl":"/edu-bible/9005/1/2-john-1"
            },
            {....}
         ]
      },
      { 
         "book":"3 John",
         "cbrainBibleTOList":[ 
            {  
               "bookName":"3 John",
               "chapter":"1",
               "pageUrl":"/edu-bible/9007/1/3-john-1"
            },
            {...}
         ]
      }
   ]
 }

我正在尝试按书名对 JSON 数据进行分组。

我尝试如下:

型号:

public class BibleTestament
    {
        public List<CbrainBibleBooksHB> cbrainBibleBooksHB { get; set; }
    }

    public class CbrainBibleBooksHB : ObservableCollection<CbrainBibleTOList>
    {
        public string book { get; set; }
        public List<CbrainBibleTOList> cbrainBibleTOList { get; set; }
    }

    public class CbrainBibleTOList
    {
        public string chapter { get; set; }
        public string pageUrl { get; set; }
        public string bookName { get; set; }
    }

视图模型

HttpClient client = new HttpClient();
                var Response = await client.GetAsync("rest api");
                if (Response.IsSuccessStatusCode)
                {
                    string response = await Response.Content.ReadAsStringAsync();
                    Debug.WriteLine("response:>>" + response);
                    BibleTestament bibleTestament = new BibleTestament();
                    if (response != "")
                    {
                        bibleTestament = JsonConvert.DeserializeObject<BibleTestament>(response.ToString());
                    }
                    AllItems = new ObservableCollection<CbrainBibleBooksHB>(bibleTestament.cbrainBibleBooksHB);

XAML

<ContentPage.Content>
        <StackLayout>
            <ListView 
                HasUnevenRows="True"
                ItemsSource="{Binding AllItems,Mode=TwoWay}"
                IsGroupingEnabled="True">
                <ListView.GroupHeaderTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <Label 
                                Text="{Binding book}"
                                Font="Bold,20" 
                                HorizontalOptions="CenterAndExpand"
                                HorizontalTextAlignment="Center"
                                VerticalTextAlignment="Center"
                                Margin="3"
                                TextColor="Black"
                                VerticalOptions="Center"/>
                        </ViewCell>
                    </DataTemplate>
                </ListView.GroupHeaderTemplate>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.View>
                                <StackLayout
                                    HorizontalOptions="StartAndExpand"
                                    VerticalOptions="FillAndExpand"
                                    Orientation="Horizontal">

                                    <Label 
                                        Text="{Binding cbrainBibleTOList.chapter}"
                                        Font="20" 
                                        HorizontalTextAlignment="Center"
                                        VerticalTextAlignment="Center"
                                        HorizontalOptions="CenterAndExpand"
                                        TextColor="Black"
                                        VerticalOptions="Center"/>
                                </StackLayout>
                            </ViewCell.View>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
                <ListView.Footer>
                    <Label/>
                </ListView.Footer>
            </ListView>
        </StackLayout>
    </ContentPage.Content>

但运行项目时,UI 上没有显示任何数据。在输出框中获取Binding: 'book' property not found on 'System.Object[]', target property: 'Xamarin.Forms.Label.Text' 消息。在 xamarin 表单中实现列表视图的分组非常困难。谁能帮我做到这一点?我已经上传了一个示例项目here

【问题讨论】:

  • 您的样本似乎包含您的个人网址。我建议你应该删除它并使用静态数据创建一个演示。
  • @LucasZhang-MSFT 这是我的个人网址,我会在得到解决方案后删除示例。你能帮帮我吗?
  • 我无法从远程访问它。我将使用静态源对其进行测试。

标签: xamarin.forms listviewgroup


【解决方案1】:

你也可以这样做

 <ListView ItemsSource="{Binding Itens}" SeparatorColor="#010d47"  RowHeight="120" x:Name="lvEmpresaPending" SelectionMode="None">
                                        <ListView.ItemTemplate>
                                            <DataTemplate>
                                                <ViewCell>
                                                    <StackLayout>
                                                        <StackLayout Orientation="Horizontal">
                                                            <Label Text="Nome da Empresa:" FontAttributes="Bold" ></Label>
                                                            <Label Text="{Binding Main.Nome}"></Label>
                                                        </StackLayout>
                                                        <StackLayout Orientation="Horizontal">
                                                            <Label Text="CNPJ da Empresa:" FontAttributes="Bold"></Label>
                                                            <Label Text="{Binding Main.Cnpj}"></Label>
                                                        </StackLayout>
                                                        <StackLayout Orientation="Horizontal">
                                                            <Label Text="Cargo: " FontAttributes="Bold"></Label>
                                                            <Label Text="{Binding Cargo}"></Label>
                                                        </StackLayout>
                                                        <StackLayout Orientation="Horizontal">
                                                            <Label Text="Inicio" FontAttributes="Bold"></Label>
                                                            <Label Text="{Binding DataInicio}"></Label>
                                                            <Label Text="Término" FontAttributes="Bold"></Label>
                                                            <Label Text="{Binding DataFim}"></Label>

                                                        </StackLayout>

                                                    </StackLayout>
                                                </ViewCell>
                                            </DataTemplate>



public class ModelosPPP
    {
        public Empresa Main { get; set; }
        public string DataInicio { get; set; }
        public string DataFim { get; set; }
        public string Cargo { get; set; }
        public string Status { get; set; }
    }


 public class Empresa
    {
        public string Nome { get; set; }
        public string Cnpj { get; set; }
    }

【讨论】:

    【解决方案2】:

    您可以使用 Xamarin.Forms 版本 >=3.5 的最新 BindableLayout,而不是使用分组的 Listview,而且工作量更少。

    更新您的模型

    public class CbrainBibleBooksHB
    {
       public string book { get; set; }
       public List<CbrainBibleTOList> cbrainBibleTOList { get; set; }
    }
    

    XAML:

    <ScrollView>
        <FlexLayout
            BindableLayout.ItemsSource="{Binding AllItems}"
            Direction="Column"
            AlignContent="Start">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="30"/>
                            <RowDefinition Height="auto"/>
                        </Grid.RowDefinitions>
                        <Label Grid.Row="0"
                                Text="{Binding book}"
                                HorizontalOptions="FillAndExpand"
                                BackgroundColor="LightBlue"/>
                        <StackLayout Grid.Row="1"
                                        BindableLayout.ItemsSource="{Binding cbrainBibleTOList}">
                            <BindableLayout.ItemTemplate>
                                <DataTemplate>
                                    <Label Text="{Binding chapter}">
                                        <Label.GestureRecognizers>
                                            <TapGestureRecognizer Command="{Binding BindingContext.TapCommand, Source={x:Reference Name=ParentContentPage}}" CommandParameter="{Binding .}"/>
                                        </Label.GestureRecognizers>
                                    </Label>
                                </DataTemplate>
                            </BindableLayout.ItemTemplate>
                        </StackLayout>
                    </Grid>
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </FlexLayout>
    </ScrollView>
    

    注意:这里的ParentContentPage是父内容页面的x:Name,用于给命令提供参考。

    视图模型:

    class BibleTestamentViewModel : INotifyPropertyChanged
    {
        public ICommand TapCommand { get; private set; }
    
        public BibleTestamentViewModel()
        {
            TapCommand = new Command(ChapterClickedClicked);
        }
    
        private void ChapterClickedClicked(object sender)
        {
            //check value inside sender
        }
    }
    

    输出:

    【讨论】:

    • 我会试试这个。您是否参与过我的示例项目,如果是,请提供工作示例。
    • 你能分享那个样本吗?
    • 我尝试在点击一章时读取对应的物品数据。尝试如下,但得到空值。 public void OpenChapter(object sender, EventArgs args) { var item = sender as CbrainBibleTOList; if(item != null) { //代码执行不在这里 } }
    • 选择一章时我需要整个 CbrainBibleTOList 值
    【解决方案3】:

    我用静态数据测试了你的演示,你的情况有一些问题。

    首先 CbrainBibleBooksHBObservableCollection 的子类,因此您无需再设置属性 cbrainBibleTOList

    public class CbrainBibleBooksHB : ObservableCollection<CbrainBibleTOList>
    {
       public string book { get; set; }
       public List<CbrainBibleTOList> cbrainBibleTOList { get; set; }
    }
    

    其次,你设置了错误的标签绑定路径。

    <Label 
       Text="{Binding chapter}"
       ...
       />
    

    以下是我的代码,因为我无法访问您的网址,所以我使用了静态数据。

    在xml中

    ...
    <Label 
       Text="{Binding chapter}"
       HeightRequest="30"
       Font="20" 
       HorizontalTextAlignment="Center"
       VerticalTextAlignment="Center"
       HorizontalOptions="CenterAndExpand"
       TextColor="Black"
       VerticalOptions="Center"/>
    ...
    

    在视图模型中

    namespace TestamentSample
    {
        public class BibleTestamentViewModel 
        {
            
    
            public ObservableCollection<CbrainBibleBooksHB> AllItems
            {
                get;set;
            }
    
            public BibleTestamentViewModel()
            {
    
                
                var cbrainBibleBooksHB = new CbrainBibleBooksHB() {book = "group1",};
    
                cbrainBibleBooksHB.Add(new CbrainBibleTOList() { chapter = "1111" });
                cbrainBibleBooksHB.Add(new CbrainBibleTOList() { chapter = "2222" });
                cbrainBibleBooksHB.Add(new CbrainBibleTOList() { chapter = "3333" });
                cbrainBibleBooksHB.Add(new CbrainBibleTOList() { chapter = "4444" });
                cbrainBibleBooksHB.Add(new CbrainBibleTOList() { chapter = "5555" });
    
    
                var cbrainBibleBooksHB2 = new CbrainBibleBooksHB() { book = "group2", };
    
                cbrainBibleBooksHB2.Add(new CbrainBibleTOList() { chapter = "6666" });
                cbrainBibleBooksHB2.Add(new CbrainBibleTOList() { chapter = "7777" });
                cbrainBibleBooksHB2.Add(new CbrainBibleTOList() { chapter = "8888" });
                cbrainBibleBooksHB2.Add(new CbrainBibleTOList() { chapter = "9999" });
                cbrainBibleBooksHB2.Add(new CbrainBibleTOList() { chapter = "0000" });
    
                AllItems = new ObservableCollection<CbrainBibleBooksHB>() {
                    cbrainBibleBooksHB,cbrainBibleBooksHB2
                };
            }
           
        }
    }
    
    
    public class CbrainBibleBooksHB : ObservableCollection<CbrainBibleTOList>
    {
      public string book { get; set; }      
    }
    

    你应该确保你从远程url下载的对象与我的演示具有相同的级别。

    【讨论】:

    猜你喜欢
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    相关资源
    最近更新 更多