【问题标题】:Populating XAML ListView ItemsSource programmatically以编程方式填充 XAML ListView ItemsSource
【发布时间】:2019-12-12 18:04:48
【问题描述】:

我正在尝试创建一个 Xamarin 跨平台应用程序。 我选择了一个模板,现在我有一个 MainPage 和 ItemsPage。 我认为 ItemsPage 是由 MainPage 调用的。

我在 ItemsPage.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"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="App1.Views.ItemsPage"
             Title="{Binding Title}"
             x:Name="BrowseItemsPage">

    <ContentPage.ToolbarItems>
        <ToolbarItem Text="Add" Clicked="AddItem_Clicked" />
    </ContentPage.ToolbarItems>

    <StackLayout>
        <ListView x:Name="ItemsListView"
                ItemsSource="{Binding Items}"
                VerticalOptions="FillAndExpand"
                HasUnevenRows="true"
                RefreshCommand="{Binding LoadItemsCommand}"
                IsPullToRefreshEnabled="true"
                IsRefreshing="{Binding IsBusy, Mode=OneWay}"
                CachingStrategy="RecycleElement"
                ItemSelected="OnItemSelected">

            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Padding="10">
                            <Label Text="{Binding Text}" 
                                d:Text="{Binding .}"
                                LineBreakMode="NoWrap" 
                                Style="{DynamicResource ListItemTextStyle}" 
                                FontSize="16" />
                            <Label Text="{Binding Description}" 
                                d:Text="Item descripton"
                                LineBreakMode="NoWrap"
                                Style="{DynamicResource ListItemDetailTextStyle}"
                                FontSize="13" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>

    </ContentPage>

ItemsPage.cs 中的这段代码

    public ItemsPage()
    {
            InitializeComponent();

            BindingContext = viewModel = new ItemsViewModel();
            string[] files = folderEntryListinAssets("folderName");

            ObservableCollection<String> entries = new ObservableCollection<String>();

            for (var i=0;i<files.Length;i++)
            {
               Console.WriteLine("app output - entry "+files[i]);
               entries.Add(files[i]);
            }
            ItemsListView.ItemsSource = entries;           
        }


    private String[] folderEntryListinAssets(String folderName)
    {                           
                switch (Device.RuntimePlatform)
                {
                    case Device.Android:
                    Context context = Android.App.Application.Context;

                    String[] list=context.Assets.List(folderName);
                    Console.WriteLine("app output - list size " + list.Length);
                    for (int i = 0; i < list.Length; i++)
                    { Console.WriteLine("app output - entry "+list.GetValue(i).ToString()); }


                    return list;
                   /* case Device.UWP:
                        path = "ms-appx-web:///";
                        return path;
                case Device.iOS:
                    path = NSBundle.MainBundle.BundlePath;
                    return path;*/
                    default:

                    return null;
                }

我什么都没看到。

请注意,我删除了 XAML 中的默认字符串,它们已正确显示。

现在我需要以编程方式设置 ItemsSource,如上所示。

我看到这些条目在控制台日志中被创建为字符串。

我的代码有什么问题?

【问题讨论】:

  • 在 XAML 中,您将 listview 的 ItemsSource 设置为绑定 (ItemsSource="{Binding Items}"),即 ItemSource 将在 viewmodel 中设置,但为什么还要在代码隐藏中设置 ItemSource?
  • @Vahid 我尝试了你的建议,但它没有显示任何内容如果我将 'ItemsSource="{Binding entries}"' 放入 XAML 并评论 'ItemsListView.ItemsSource = entries;'在代码中,前提是我现在使用我接受的答案
  • 您需要决定如何设置 ItemSource,如果在代码隐藏中,那么我在答案中的做法是正确的,但如果在 viewmodel 中,则需要在代码中注释设置 ItemSource -behind 并将其设置在 viewmodel 中,即 ItemsViewModel 中,必须正确设置为 viewmodel。
  • @Vahid 是的,我逐渐记住了这一切是如何工作的,所以我恢复了 'ItemsSource="{Binding Items}"',然后设置 'ObservableCollection entries = new ObservableCollection();'但如果我把 viewModel.Items = entries;它不显示任何内容。
  • 那我猜是viewmodel设置不正确。可能 Items 属性没有调用 OnPropertyChanged。但这将是一个新问题,可以作为 stackoverflow 上的一个新问题提出。

标签: c# listview xamarin data-binding cross-platform


【解决方案1】:

问题在于您在 viewcell 中设置 ItemSource 和绑定的方式。 根据您的 viewcell,它希望每个项目都是一个模型,其中有两个属性:TextDescription,即 ItemSourse 必须是该模型的集合。

你应该有这样的模型:

public class MyModel{
    public string Text{get;set;}
    public string Description{get;set;}
}

你需要像这样设置 ItemSource:

ObservableCollection<MyModel> entries = new ObservableCollection<MyModel>();

for (var i = 0; i<files.Length; i++)
{
Console.WriteLine("app output - entry " + files[i]);

var model = new MyModel
{
    Text = "text value",
    Description = "description value"
};

entries.Add(model);
}
ItemsListView.ItemsSource = entries;

最后取决于你如何填充每个模型,即文本和描述。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多