【问题标题】:ListView.ItemTemplate not being set and events not firingListView.ItemTemplate 未设置且事件未触发
【发布时间】:2017-02-25 20:33:51
【问题描述】:

我正在开发一个 Xamarin 项目以了解它的工作原理,但我遇到了一个我似乎无法解决的问题。

我有一个 listview itemplate 存储在我的 XAML 中的 listview 标记内,它定义了一个标签,并且该标签的文本是来自数据源的绑定集,尽管当我的项目通过 itemsource 加载时它正在使用我的覆盖tostring 而不是我的绑定,这会导致问题。我的 itemtapped 事件处理程序也没有工作,似乎没有被触发。我正在使用 VS for mac。

这是我的表单 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="BrainStorageApp.MainPage"
             Title="View Notes">
  <ListView ItemsSource="{Binding Items}"
            x:Name="MainListView"
            HasUnevenRows="true"
            IsGroupingEnabled="true"
            IsPullToRefreshEnabled="true"
            IsEnabled="true"
            CachingStrategy="RecycleElement"
            IsRefreshing="{Binding IsBusy, Mode=OneWay}"
            RefreshCommand="{Binding RefreshDataCommand}">
    <ListView.Header>
      <StackLayout Padding="40" 
                   Orientation="Horizontal"
                   HorizontalOptions="FillAndExpand"
                   BackgroundColor="{StaticResource Primary}}">
        <Label Text="Your Notes"
               HorizontalTextAlignment="Center"
               HorizontalOptions="FillAndExpand"
               TextColor="White"
               FontAttributes="Bold"/>
      </StackLayout>
    </ListView.Header>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Label Text="{Binding title}" FontSize="14" />
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

希望我不只是愚蠢和遗漏了什么,因为我的 XAML 似乎构建良好并且我的 itemsource 似乎工作正常。如果您需要查看我的代码,只需发表评论,我会进行编辑以提供。

编辑:不确定是否有任何区别,但此页面位于标签页中。

编辑 2:这是我的主要 xaml.cs 文件的代码,根据要求。

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace BrainStorageApp
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MainPage : ContentPage
    {

        private BrainstorageApiClass BrainstorageClass;
        private UserClass User;

        public MainPage(string username)
        {
            InitializeComponent();
            BrainstorageClass = new BrainstorageApiClass();
            User = new UserClass();
            User.Username = username;
            BindingContext = new ListViewPageViewModel(BrainstorageClass.LoadNotes(User.Username));
        }

        void Handle_ItemTapped(object sender, Xamarin.Forms.ItemTappedEventArgs e)
        {
            Console.WriteLine(sender.ToString());
        }
    }



    class ListViewPageViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<NoteItem> Items { get; }

        public ListViewPageViewModel(List<NoteItem> list)
        {
            Items = new ObservableCollection<NoteItem>(list);
            RefreshDataCommand = new Command(
                async () => await RefreshData());
        }

        public ICommand RefreshDataCommand { get; }

        async Task RefreshData()
        {
            IsBusy = true;
            //Load Data Here
            await Task.Delay(2000);

            IsBusy = false;
        }

        bool busy;
        public bool IsBusy
        {
            get { return busy; }
            set
            {
                busy = value;
                OnPropertyChanged();
                ((Command)RefreshDataCommand).ChangeCanExecute();
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;
        void OnPropertyChanged([CallerMemberName]string propertyName = "") =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

编辑 3:

注意事项

namespace BrainStorageApp
{
    public class NoteItem
    {
        public int id;
        public string title;
        public string content;
        public DateTime createdat;
        public DateTime updatedat;

        public NoteItem(JToken Token)
        {
            id = int.Parse(Token["id"].Value<string>());
            title = Token["Note_Title"].Value<string>();
            content = Token["Note_Content"].Value<string>();
            createdat = DateTime.Parse(Token["created_at"].Value<string>());
            updatedat = DateTime.Parse(Token["updated_at"].Value<string>());
        }

        public override string ToString()
        {
            return title;
        }
    }
}

【问题讨论】:

  • 请显示 ViewModel(s) 以及您如何设置 BindingContext。
  • @Sven-MichaelStübe 已添加 :) 请注意,我删除了事件处理程序,因为我认为修复此问题可以修复:P
  • @Sven-MichaelStübe 添加

标签: c# xaml listview xamarin


【解决方案1】:

如果你想绑定一些东西,它必须是一个属性。 title 不是财产。

public class NoteItem
{
    public int id {get;}
    public string title {get;}
    public string content {get;}
    public DateTime createdat {get;}
    public DateTime updatedat {get;}
}

注意

通常在 C# 中,属性以大写字母开头。

public class NoteItem
{
    public int Id {get;}
    public string Title {get;}
    public string Content {get;}
    public DateTime CreateDate {get;}
    public DateTime UpdateDate {get;}
}

但是不要忘记更新你的绑定。

<Label Text="{Binding Title}" FontSize="14" />

【讨论】:

  • 不幸的是,这似乎并不能解决问题。我删除了我的 ToString() 只是为了确定它正在使用什么,现在文本是“Brainstorageapp.NoteItem”
  • 找到了它为什么不工作,但如果你可以的话,我想要一些关于它的信息。在我的列表视图 XAML 中,我删除了 'IsGroupingEnabled="true"' 并修复了它。为什么会发生这种情况?
  • 是的,如果您使用分组,您的 ItemsSource 必须是 ObservableCollection&lt;ObservableCollection&lt;NoteItem&gt;&gt; 或者换句话说:项目列表的列表。下面是一个分组示例:github.com/xamarin/xamarin-forms-samples/tree/master/…
  • 嗯,好的,谢谢你在我的问题上帮助我,我的习惯是 WinForms 这么久了,所以 XAML 设计等是非常新的:P 我会将你的答案标记为已接受
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 2013-04-09
  • 2015-07-25
相关资源
最近更新 更多