以编程方式填充 XAML ListView ItemsSource

Posted

技术标签:

【中文标题】以编程方式填充 XAML ListView ItemsSource【英文标题】:Populating XAML ListView ItemsSource programmatically 【发布时间】: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。但这将是一个新问题,可以作为 *** 上的一个新问题提出。 【参考方案1】:

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

你应该有这样的模型:

public class MyModel
    public string Textget;set;
    public string Descriptionget;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;

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

【讨论】:

以上是关于以编程方式填充 XAML ListView ItemsSource的主要内容,如果未能解决你的问题,请参考以下文章

WPF ListView - 如何以编程方式添加项目?

ListView 以编程方式突出显示单行或多行

XAML 在 ListView 中具有来自 AppResources 的 Labeltext

网格列中的 XAML 拉伸文本块

(C#) 需要以编程方式添加一些 xaml

在 App.xaml 中添加按钮并以编程方式将其添加到其他 xaml 页面 Windows 运行时应用