【问题标题】:Binding ViewModel Property with ListView in View in Xamarin在 Xamarin 的视图中将 ViewModel 属性与 ListView 绑定
【发布时间】:2018-02-12 23:40:27
【问题描述】:

我只是 Xamarin 的新手。我正在尝试将属性值与 ListView 绑定,但没有成功。尝试在互联网上搜索,但没有奏效。此外,属性更改事件始终为空。这是我的视图模型

namespace DemoApp.ViewModels
{
    class MainViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<ShippingDetail> ShippingDetailList { get; set; }

    public ObservableCollection<ShippingDetail> ShippingDetails

        {
            get { return ShippingDetailList; }
            set
            {
                ShippingDetailList = value;
                OnPropertyChanged("Changed");
            }
        }

         public async Task GetShippingDataAsync(string TrackID)
    {
        GenericRestClient<ShippingDetail> client = new GenericRestClient<ShippingDetail>();

        ShippingDetails = await client.GetAsyncByID(TrackID);

    }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string property)
        {
            var changed = PropertyChanged;

            if (changed == null)
                return;

            changed(this, new PropertyChangedEventArgs(property));
        }

    }
}

这是我的 View 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="DemoApp.TrackByID"
               Title="Mex World Wide"
             xmlns:local="clr-DemoApp"
             xmlns:ViewModels="clr-DemoApp.ViewModels">



    <ContentPage.BindingContext>
        <ViewModels:MainViewModel/>
    </ContentPage.BindingContext>

    <ContentPage.Content>
        <AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">

            <StackLayout AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
                <ScrollView>
                    <StackLayout>
                        <StackLayout Padding="30" Spacing="2" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand">
                            <Entry x:Name="TrackIDText"  HorizontalTextAlignment="Center" Placeholder="Enter Your Shipment Tracking ID" TextChanged="TrackID_TextChanged"></Entry>

                        </StackLayout>
                        <StackLayout Padding="30" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand">
                            <Button x:Name="TrackBtn" Text="Track" IsEnabled="False" BackgroundColor="Olive" Clicked="TrackBtn_Clicked"/>
                            <Button x:Name="ScanBtn" Text="Scan Barcode" IsEnabled="True" BackgroundColor="Azure" Clicked="ScanBtn_Clicked"/>
                        </StackLayout>
                    </StackLayout>
                </ScrollView>
                <StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand">
                    <ListView  x:Name="ShippingLV"
                  RowHeight="60"
                               ItemsSource="{Binding ShippingDetails}"/>
                </StackLayout>
            </StackLayout>

            <StackLayout x:Name="ActivityIndsL" IsVisible="False" Padding="12"
                 AbsoluteLayout.LayoutFlags="PositionProportional"
                 AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">

                <ActivityIndicator x:Name="TrackingActivity" Color ="#FF4081"/>

                <Label Text="Please Wait while Details are being fetched..." HorizontalOptions="Center" TextColor="#FF4081"/>

            </StackLayout>

        </AbsoluteLayout>


    </ContentPage.Content>


</ContentPage>

我正在尝试将 ShippingDetails 与 ListView 绑定为其 ItemSource,这在按钮单击事件中被调用。以下是 XAML 视图的代码

private async void TrackBtn_Clicked(object sender, EventArgs e)
    {
        MainViewModel obj = new MainViewModel();

        ActivityIndsL.IsVisible = true;
        TrackingActivity.IsRunning = true;

        TrackingActivity.IsVisible = true;
        TrackBtn.IsEnabled = false;
        ScanBtn.IsEnabled = false;

        await obj.GetShippingDataAsync(TrackIDText.Text);

        ActivityIndsL.IsVisible = false;
        TrackingActivity.IsRunning = false;
        TrackingActivity.IsVisible = false;
        TrackBtn.IsEnabled = true;
        ScanBtn.IsEnabled = true;



    }

请纠正我做错的地方。 谢谢

【问题讨论】:

    标签: c# .net xamarin mvvm xamarin.forms


    【解决方案1】:

    您的代码有一些问题。首先,你用错误的值调用OnPropertyChanged。它应该是已更改的属性的名称,如下所示:

    public ObservableCollection<ShippingDetail> ShippingDetails
    {
        get { return ShippingDetailList; }
        set
        {
            ShippingDetailList = value;
            OnPropertyChanged("ShippingDetails");
        }
    }
    

    此外,您已经在 XAML 中将 MainViewModel 设置为 BindingContext:

    <ContentPage.BindingContext>
        <ViewModels:MainViewModel/>
    </ContentPage.BindingContext>
    

    在按钮的单击事件中无需再次执行此操作。我不会在每次单击按钮时都创建一个新实例,而是像这样引用已经存在的视图模型:

    private async void TrackBtn_Clicked(object sender, EventArgs e)
    {
        MainViewModel vm = this.BindingContext as MainViewModel;
        await vm.GetShippingDataAsync(TrackIDText.Text);
    }
    

    编辑:我还要在您的代码中修复一件事。我将ShippingDetailList 定义为私有实例字段,因为ShippingDetails 属性用于将其暴露给外界。这不会真正影响您的代码的工作方式,但它更接近于 正确 C# 方式。

    private ObservableCollection<ShippingDetail> shippingDetailList;
    

    Here's一些关于字段的好读物,如果你有兴趣的话。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-07
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多