【问题标题】:Xamarin, Using View Model with ViewCell messes up ViewModel BindingXamarin,将 View Model 与 ViewCell 一起使用会破坏 ViewModel 绑定
【发布时间】:2020-03-28 06:32:49
【问题描述】:

当我为此写标题时,我一直在查看我得到的所有建议,但没有人可以帮助我解决我的问题。由于这是我在这里的第一个问题,如果我问错了,请原谅我,如果我需要详细说明,请告诉我。

然而,我正在使用 ListView 在 Xamarin 中工作。 listView 是通过将 ItemSource 设置为 List 来填充的,该 List 包含我的一个扩展 ViewCell 类的类,这基本上如下所示。

问题

我遇到的问题是使用 MeasurePointView.xaml.cs 类的 ViewModel。当尝试访问为 MeasurePointView.xaml.cs 设置为 BindingContext 的 MeasurePointViewModel 中的任何属性时,例如:来自调试器的[0:] Binding: 'MeasurePointProps' property not found on 'Mobile.Pages.MeasurePointView', target property: 'Xamarin.Forms.Label.Text',当然屏幕上什么也没有显示。

所以我的问题是:如何在 ViewCell 类“MeasurePointView”和 ViewModel“MeasurePointViewViewModel”之间设置绑定以使其正常工作?

另外,请让我知道我对数据绑定的误解有多严重。只是我一直在使用这种方法在整个应用程序中工作,除了这里。

只是为了澄清: 页面扩展 BasePage(扩展 ContentPage) 并且 Viewmodel 派生自 BaseViewModel(基本上实现了 INotifyPropertyChanged)

ListOneView.xaml.cs

using Mobile.Controls;
using Mobile.Pages;
using Mobile.ViewModels;
using System.Collections.ObjectModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Mobile.Views {
  [XamlCompilation(XamlCompilationOptions.Compile)]
  public partial class ListOneView : BasePage {

    public ListView ListView;

    public ObservableCollection<MeasurePoint> MeasurePointList { get; set; }

    public ListOneView(ObservableCollection<MeasurePoint> list) {
      MeasurePointList = list;
      InitializeComponent();
      InitializeBindings();
      InitializeMeasurePoints();
    }

    public void InitializeBindings() {
      BindingContext = ViewModel = new ListOneViewViewModel(MeasurePointList);
    }

    private void InitializeMeasurePoints() {
      ListView = MeasurePointListView;
      MeasurePointListView.ItemTemplate = new DataTemplate(typeof(MeasurePointView));
      MeasurePointListView.ItemsSource = (ViewModel as ListOneViewViewModel).MeasurePointViewList;
    }
}


ListOneView.xaml


<?xml version="1.0" encoding="utf-8" ?>
<pages:BasePage
    xmlns:pages="clr-namespace:Mobile.Pages"
    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="Mobile.Views.ListOneView"
    BackgroundColor="{StaticResource BackgroundGrey}">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Label">
                <Setter Property="FontSize" Value="12" />
                <Setter Property="TextColor" Value="Black" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <ListView
        x:Name="MeasurePointListView"
        BackgroundColor="{StaticResource BackgroundGrey}"
        HasUnevenRows="True">
        <!--Empty-->
    </ListView>

</pages:BasePage>


ListOneViewViewModel.cs


using Mobile.Controls;
using Mobile.Pages;
using System.Collections.ObjectModel;

namespace Mobile.ViewModels {
  public class ListOneViewViewModel : BaseViewModel {

    public ObservableCollection<MeasurePointView> MeasurePointViewList { get; set; }

    public ListOneViewViewModel(ObservableCollection<MeasurePoint> measurePointList) {
      if (MeasurePointViewList == null)
        MeasurePointViewList = new ObservableCollection<MeasurePointView>();

      foreach (MeasurePoint mp in measurePointList) {
        MeasurePointViewList.Add(new MeasurePointView() {
          MeasurePoint = mp
        });
      }
    }
  }
}

MeasurePointView.xaml.cs


using Mobile.Controls;
using Mobile.ViewModels;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace Mobile.Pages {
  [XamlCompilation(XamlCompilationOptions.Compile)]
  public partial class MeasurePointView : ViewCell {
    public MeasurePoint MeasurePoint { get; set; }
    public MeasurePointView() {
      InitializeComponent();
      InitializeBindings();
    }

    private void InitializeBindings() {
      BindingContext = new MeasurePointViewViewModel() {
        MeasurePointProps = this.MeasurePoint
      };
    }
  }

  public class MeasurePointViewViewModel : BaseViewModel {
    public MeasurePoint MeasurePointProps { get; set; }
  }
}

MeasurePointView.xaml


<?xml version="1.0" encoding="UTF-8"?>
<ViewCell
    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"
    x:Class="Mobile.Pages.MeasurePointView"
    mc:Ignorable="d">
    <ViewCell.View>
        <ContentView>
            <Label Text="{Binding MeasurePointProps.Title}" />
        </ContentView>
    </ViewCell.View>
</ViewCell>

【问题讨论】:

  • ListView 中的每个项目都会自动设置它的 BindingContext。您不需要自己执行此操作。
  • 好的,谢谢,但我希望将其设置为 ViewModel,我将其分配到自己的类中。不仅仅是 xaml.cs 类
  • 你无缘无故地为自己创造了很多额外的工作。如果您的ItemsSourceList&lt;x&gt;,则ListView 中的每个单元格将具有对应xBindingContext。我不清楚你想通过自己的方式来完成什么。
  • 原因是将一些逻辑与裸露的“视觉逻辑”分开,因为这是一长串列表和视觉逻辑的结尾。我想将 xaml.cs 用于视觉逻辑,而我想绑定的视图模型用于更多面向数据的逻辑。它将用于验证输入并将其发送到 API 通信。

标签: listview xamarin binding viewmodel datatemplate


【解决方案1】:

我得到例如:[0:] 绑定:在“Mobile.Pages.MeasurePointView”上找不到“MeasurePointProps”属性,目标属性:来自调试器的“Xamarin.Forms.Label.Text”,当然什么也没有显示在屏幕上。

MeasurePoint.cs

public class MeasurePoint
{
    public string Title { get; set; }
    public string Point { get; set; }

}

MeasurePointViewViewModel.cs

public class MeasurePointViewViewModel : INotifyPropertyChanged
{
    public MeasurePointViewViewModel()
    {
        MeasurePointProps = new MeasurePoint() { Point = "B", Title = "2" };
    }

    private MeasurePoint _MeasurePointProps;
    public MeasurePoint MeasurePointProps
    {
        get { return _MeasurePointProps; }
        set
        {
            _MeasurePointProps = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

解决方案 1:

如果要绑定 MeasurePointProps.Title,可以直接用 MeasurePointViewViewModel 设置 BindingContent。

Xaml:

<Label Text="{Binding MeasurePointProps.Title}"/>

代码:

  public MainPage()
    {
        InitializeComponent();
        InitializeBindings();
    }

    private void InitializeBindings()
    {
        BindingContext = new MeasurePointViewViewModel();
    }

解决方案 2:

如果要绑定Title,可以查看下面的代码。

Xaml:

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

代码:

public MainPage()
    {
        InitializeComponent();
        InitializeBindings();
    }

    private void InitializeBindings()
    {
        //BindingContext = new MeasurePointViewViewModel();
        BindingContext = new MeasurePointViewViewModel().MeasurePointProps;
    }

【讨论】:

    【解决方案2】:

    我认为你有点复杂了。将 ListView 与视图单元一起使用非常简单。您可以创建 ListView 并定义自己的 ItemTemplate 并直接在其中开始使用 ViewCell。您还可以创建自己的自定义视图单元格并使用它。

    <?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="demoListView.ImageCellPage">
        <ContentPage.Content>
            <ListView  x:Name="listView">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout BackgroundColor="#eee" Orientation="Vertical">
                                <StackLayout Orientation="Horizontal">
                                    <Image Source="{Binding image}" />
                                    <Label Text="{Binding title}" TextColor="#f35e20" />
                                    <Label Text="{Binding subtitle}" HorizontalOptions="EndAndExpand" TextColor="#503026" />
                                </StackLayout>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </ContentPage.Content>
    </ContentPage>
    

    有关如何将 ListView 与视图单元格一起使用的更多信息,请参阅下面的链接。

    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/listview/customizing-cell-appearance

    【讨论】:

    • @Burritobreakfast:如果我的回复对你有帮助,请记得将我的回复标记为答案,谢谢:)
    猜你喜欢
    • 2021-11-26
    • 2021-04-05
    • 2011-01-21
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 2013-06-14
    相关资源
    最近更新 更多