【问题标题】:ItemTemplate for list of items in XamarinXamarin 中项目列表的 ItemTemplate
【发布时间】:2020-10-11 04:50:15
【问题描述】:

我有一个ListView 和一个ItemTemplate。对于我的ItemSource 中的每个项目,我想遍历项目中的一个属性并在我的ViewCell 中创建一个部分。

所以每个项目都是Download

public class Download
{
    public string Title { get; set; }

    public IEnumerable<SectionDownload> SectionDownloads { get; set; }
}

SectionDownload 看起来像这样:

public class SectionDownload
{
    public long TotalBytes { get; set; }

    public long DownloadedBytes { get; set; }

    public int PercentDownloaded { get => (int)((DownloadedBytes / TotalBytes) * 100); }
}

还有我的ListView,其中Downloads 在我的ViewModel 中是ObservableCollection&lt;Download&gt;

<ListView x:Name="DownloadsListView" SelectionMode="None" ItemsSource="{Binding Downloads}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackLayout Padding="10">
                <Label Text="{Binding Title}"
                            d:Text="{Binding .}"
                            LineBreakMode="NoWrap"
                            Style="{DynamicResource ListItemTextStyle}"
                            FontSize="16" />
                <!-- Here I would like each SectionDownload to display the percentage downloaded -->
            </StackLayout>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

【问题讨论】:

    标签: c# xamarin mvvm xamarin.forms data-binding


    【解决方案1】:

    你可以像这样显示部分。

    <ListView x:Name="DownloadsListView" SelectionMode="None" ItemsSource="{Binding Downloads}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackLayout Padding="10">
                <Label Text="{Binding Title}"
                            d:Text="{Binding .}"
                            LineBreakMode="NoWrap"
                            Style="{DynamicResource ListItemTextStyle}"
                            FontSize="16" />
                <StackLayout BindableLayout.ItemsSource="{Binding SectionDownloads}">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <ProgressBar Progress="{Binding PercentDownloaded}" />
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </StackLayout>
            </StackLayout>
        </DataTemplate>
    </ListView.ItemTemplate>
    

    PercentDownloaded 的值应该在 0 到 1 的范围内翻倍,并且您必须在 SectionDownload 类中实现 INotifyPropertyChange 以实时更新进度。

    【讨论】:

    • 为了方便测试,我将 ListView 包装在 RefreshView 中,并带有一个加载下载的命令。我将 ProgressBar 更改为标签。当我尝试将下载添加到我的 ObservableCollection 时,我收到错误 System.InvalidCastException: Specified cast is not valid.
    • 由于这个答案提供了大部分答案,我将其标记为已接受的答案。我提供的代码中有一个错误,导致它无法工作。所以就像@cole-xia-msft 正确指出的那样,StackLayout 需要包装在 ViewCell 中。
    【解决方案2】:

    这个错误是因为你没有把Cell包裹在DataTemplate里面。

    修改为

    <ListView x:Name="DownloadsListView" SelectionMode="None" ItemsSource="{Binding Downloads}">
    <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>      //add this line
            <StackLayout Padding="10">
                <Label Text="{Binding Title}"
                            d:Text="{Binding .}"
                            LineBreakMode="NoWrap"
                            Style="{DynamicResource ListItemTextStyle}"
                            FontSize="16" />
                <StackLayout BindableLayout.ItemsSource="{Binding SectionDownloads}">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <ProgressBar Progress="{Binding PercentDownloaded}" />
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </StackLayout>
            </StackLayout>
          </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
    

    【讨论】:

      猜你喜欢
      • 2019-03-09
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多