【问题标题】:ListView Cell Binding not finding Methods in CollectionListView 单元格绑定未在集合中找到方法
【发布时间】:2021-08-26 23:43:57
【问题描述】:

我是第一次尝试使用 MVVM 和 ListView。我在Xamarin.Forms multi column table GUI工作

我的 ViewModel 看起来像这样

    public class CodeTableViewModel : BaseViewModel
    {
        public static ObservableCollection<CodeTableRow> CodeTable { get; set; }
        public CodeTableViewModel()
        {
        }
        public class CodeTableRow : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            int codePoint;
            public CodeTableRow(int point)
            {
                codePoint = point;
            }
            public string Decimal
            {
                get
                {
                    return codePoint.ToString("D");
                }
            }
            public string Hex
            {
                get
                {
                    return codePoint.ToString("X2");
                }
            }
            public string Ascii
            {
                get
                {
                    return ((char)codePoint).ToString();
                }
            }
...

我的 XAML 看起来像这样

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:viewmodels="clr-namespace:RefCard.ViewModels" 
             x:Class="RefCard.Views.CodeTablePage"
             Title="Code Table">
    <ContentPage.Content>
        <ListView x:DataType="viewmodels:CodeTableViewModel" ItemsSource="{Binding CodeTable}">
            <ListView.Header>
                <Grid BackgroundColor="Black">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Label Text="Dec" HorizontalOptions="Fill"  Grid.Column="0"   FontSize="Medium" FontAttributes="Bold" BackgroundColor="MediumBlue" TextColor="White" HorizontalTextAlignment="Center" Margin="1"/>
                    <Label Text="Hex" HorizontalOptions="Fill"  Grid.Column="1"  FontSize="Medium" FontAttributes="Bold" BackgroundColor="MediumBlue" TextColor="White" HorizontalTextAlignment="Center" Margin="0"/>
                    <Label Text="ASCII" HorizontalOptions="Fill"  Grid.Column="2"  FontSize="Medium" FontAttributes="Bold" BackgroundColor="MediumBlue" TextColor="White" HorizontalTextAlignment="Center" Margin="0"/>
                </Grid>
            </ListView.Header>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid BackgroundColor="Black">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Label Grid.Column="0" Text ="{Binding Decimal}" HorizontalOptions="Fill" BackgroundColor="LightBlue" HorizontalTextAlignment="Center" Margin="1" TextColor="Black"></Label>
                            <Label Grid.Column="1" Text ="{Binding Hex}" HorizontalOptions="Fill" BackgroundColor="LightBlue" HorizontalTextAlignment="Center" Margin="0"></Label>
                            <Label Grid.Column="2" Text ="{Binding Ascii}" HorizontalOptions="Fill" BackgroundColor="LightBlue" HorizontalTextAlignment="Center" Margin="0"></Label>
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>
</ContentPage>

在页面构造函数中我做了CodeTableViewModel.CodeTable = new ObservableCollection&lt;CodeTableViewModel.CodeTableRow&gt;(); 和一堆Add。

我尝试破解一堆变体,但基本错误是 XFC0045 绑定:在“RefCard.ViewModels.CodeTableViewModel”上找不到属性“十进制”。 RefCard C:\Users\Charles\source\repos\RefCard\RefCard\Views\CodeTablePage.xaml 38

我该如何解决?

【问题讨论】:

  • 1) 去掉 x:DataType="viewmodels:CodeTableViewModel",2) CodeTableRow 的类定义不应该嵌套在 CodeTableViewModel 中,3) CodeTableViewModel 应该在构造函数中初始化它的所有者属性,页面不应该这样做

标签: listview xamarin.forms data-binding


【解决方案1】:

根据你的代码,Jason have provided 给你三个建议。

首先,不需要添加x:DataType="viewmodels:CodeTableViewModel",因为ListView的ItemsSource="{Binding CodeTable}",然后是CodeTableRow的CodeTable列表。

其次,来自这个文档Model-View-ViewModel Pattern

视图——视图负责定义用户在屏幕上看到的结构、布局和外观。

ViewModel——视图模型实现了视图可以数据绑定到的属性和命令,并通过更改通知事件通知视图任何状态更改。

模型——模型类是封装应用数据的非可视类。

所以我建议你不要在你的 ViewModel 类中添加 Model 类,这是两个独立的类。

public class CodeTableViewModel
{
    public  ObservableCollection<CodeTableRow> CodeTable { get; set; }
    public CodeTableViewModel()
    {
        CodeTable = new ObservableCollection<CodeTableRow>();
    }
}

public class CodeTableRow : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    int codePoint;

    public CodeTableRow(int point)
    {
        codePoint = point;
    }

    public string Decimal
    {
        get
        {
            return codePoint.ToString("D");
        }
    }

    public string Hex
    {
        get
        {
            return codePoint.ToString("X2");
        }
    }

    public string Ascii
    {
        get
        {
            return ((char)codePoint).ToString();
        }
    }
 }

通常我们在 ViewModel 类中获取一些数据,然后将 ViewModel 绑定到当前 contentPage 的 BindingContext。

public class CodeTableViewModel
{
    public  ObservableCollection<CodeTableRow> CodeTable { get; set; }

    public CodeTableViewModel()
    {
        CodeTable = new ObservableCollection<CodeTableRow>()
        {
            new CodeTableRow(12),
            new CodeTableRow(18),
            new CodeTableRow(19),
            new CodeTableRow(121),
            new CodeTableRow(124)
        };

    }
}

public Page22()
{
    InitializeComponent();

    this.BindingContext = new CodeTableViewModel();
}

如果你还想在ContentPage的构造函数中获取数据,可以看看下面的代码,不过我不建议这样做。

public partial class Page22 : ContentPage, INotifyPropertyChanged
{
    private CodeTableViewModel _viewmodel;

    public CodeTableViewModel viewmodel
    {
        get { return _viewmodel; }
        set
        {
            _viewmodel = value;
            RaisePropertyChanged("viewmodel");
        }
    }

    public Page22()
    {
        InitializeComponent();
        viewmodel = new CodeTableViewModel();
        viewmodel.CodeTable = new ObservableCollection<CodeTableRow>()
        {
            new CodeTableRow(12),
            new CodeTableRow(18),
            new CodeTableRow(19),
            new CodeTableRow(121),
            new CodeTableRow(124)
        };

        this.BindingContext = viewmodel;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

【讨论】:

  • @Jason, Cherry Bu -- 这是很棒的东西,谢谢。我想感谢你的帮助。我需要一点时间来实现所有这些。
【解决方案2】:

简而言之,您的 ListView 项目数据类型不正确

  1. 在单个类中定义您的模型
    (无需为模型类实现 INotifyPropertyChanged,而是在 BaseViewModel 中实现)
namespace YourProj.Models
{
    public class CodeTableRow
    {
        public string Decimal { get; set; }
        ...
    }
}
  1. 在 CodeTableViewModel 中定义 CodeTableRow 的属性
    public class CodeTableViewModel : BaseViewModel
    {
        public static ObservableCollection<CodeTableRow> CodeTable { get; set; }
        public CodeTableViewModel()
        {
        }

        private CodeTableRow _codeTableRow;
        public CodeTableRow CodeTableRow
        {
            get => _codeTableRow;
            set => SetProperty(ref _codeTableRow, value);
        }
    }
  1. 更正您的 ListView 项的 DataType
<ContentPage
    xmlns:models="clr-namespace:YourProj.Models"
    ...>
<ListView ...>
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="models:CodeTableRow">
        ....
</ListView>

【讨论】:

  • 我做了上面和下面建议的所有事情(不是“如果你仍然想获取数据......:)。1.我收到错误“找不到类型'models:CodeTableRow' ...” 2. 我收到错误“无法解析类型“模型:CodeTableRow”。 3. 我在 ListView 绑定“没有为 CodeTable 找到数据上下文”上收到 IntelliSense 错误——这就是导致我添加 x:DataType(并使错误消失)的原因。
  • 知道了!错过了上面的一些。谢谢你们。我会尽量不把它当作一个死记硬背的答案,而是尝试从中学习 MVVM 组织。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-22
相关资源
最近更新 更多