【问题标题】:xamarin.forms Update Listview with pickerxamarin.forms 使用选择器更新 Listview
【发布时间】:2023-09-22 16:18:01
【问题描述】:

我有一个 xamarin 表单应用程序,它在顶部有一个选择器,在它下面有一个列表视图。当应用程序启动时,选择器上的数据将从 Web API 绑定。然后根据选择器值完成另一个 API 调用列表视图将加载。当用户更改选择器的值时,应该更新 Listview。我没有使用任何视图模型。我有一个用于 API 调用的帮助程序类,我将 json 结果设置为列表并将其设置为我的列表视图的 itemsource。我以某种方式实现了它,但它并不顺利,当我更改picker.NB 的值时,有时会出现“内存不足异常”错误:我正在使用带有 Rg.popup.Plugin 的自定义选择器。这会将选定的值设置为标签。

我的问题是

  1. 这是加载列表视图的正确方法,该列表视图在更改选择器的值时会更新?我应该做哪些更正?
  2. 我应该为这个场景使用视图模型(MVVM)模式吗?我的列表将包含更大的数据。

我的 xamal.cs 注意: APICall 类将以正确的格式返回 json。

  public partial class List : ContentPage
    {
        string weekstart;
        string WeekString;
        ObservableCollection<PickerData> resultObjcallForPicker = new ObservableCollection<PickerData>();       
        public TimeSheetList()
        {
            InitializeComponent();
            Thread loadScreenItemsThread = new Thread(new ThreadStart(LoadScreenItemsAsync));
            loadScreenItemsThread.Start();               
        }
         public async void LoadScreenItemsAsync()
         {                             
          //Picker Data loading       
            string postdataForPicker = "{\"Username\":\"" + Settings.userID + "\",\"ConnectionString\":\"" + Settings.String+ "\"}";
            APICall callForPicker = new APICall("/API/ListMobile/PickerData", postdataForPicker, loadingIndicator);
            try
            {
                    resultObjcallForPicker = callForPicker.APICallResult<ObservableCollection<PickerData>>();
                if (resultObjcallForPicker != null)
                {
                    WeekString = DateTime.Parse(resultObjcallForPicker[0].SDate).ToString("dd-MMM-yyyy");
                    Device.BeginInvokeOnMainThread(async () =>
                    {
                        // Setting the value of picker initially.
                    WeekStart.Text = WeekString;                                        
                    });
                    await loadList();                   
                }
                else
                {
                    Device.BeginInvokeOnMainThread(async () =>
                    {
                        UserDialogs.Instance.HideLoading();
                        await DisplayAlert("", "error occured", "OK");
                    });
                }
            }
            catch (Exception)
            {
                Device.BeginInvokeOnMainThread(async () =>
                {
                    UserDialogs.Instance.HideLoading();
                    ErrorMessageData errorMessage = new ErrorMessageData();
                    errorMessage.Flag = false; errorMessage.Message = callForPicker.errorMessage.Message;
                });
            }

        }

        //<<----------------Loading Listview----------------------->>   

        public async Task loadList()
        {       
            string postdataForList = "{\"date\":\"" + WeekStart.Text + "\"}";
            APICall callForList = new APICall("/API/ListMobile/ListForApproval", postdataForList, loadingIndicator);
            try
            {
               List<ListData> resultObjForListst = callForList.APICallResult<List<ListData>>();
                if (resultObjForListst != null)
                {                                                      
                    List.ItemsSource = resultObjForListst;
                    screenStackLayout.VerticalOptions = LayoutOptions.FillAndExpand;
                    List.IsVisible = true;              
               }
               else
                {
                    Device.BeginInvokeOnMainThread(async () =>
                    { 
                       await DisplayAlert("", "Please check network connection", "OK");
                    });
                }
            }
           catch (Exception)
            {
              Device.BeginInvokeOnMainThread(async () =>
               {
                   ErrorMessageData errorMessage = new ErrorMessageData();
                   errorMessage.Flag = false; errorMessage.Message = callForList.errorMessage.Message;
                });
            }

        }
        void Picker_tapped(object sender,EventArgs e)
            {
            PopupNavigation.PushAsync(new WeekStartPopUp(WeekStartList));
            MessagingCenter.Subscribe<MyMessage>(this, "WeekStartData", (value) =>
            {
                string receivedData = value.Myvalue;
                WeekStart.Text = receivedData;      

                  Device.BeginInvokeOnMainThread(async () =>
                {
                    try {
                        loadList();
                    }
                    catch(Exception Ex)
                    {

                    }

                });                       
            });
            }

}

感谢任何帮助。如果需要任何其他信息,请告诉我。

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    第一

    报错:sometimes gets Error as "Outof memmory exception",需要一次性获取所有数据吗?如果没有,您可以只获取所需的数据并动态更新页面。例如,您可以使用分页来请求和显示数据。

    此外,如果您确定有足够的可用内存,运行 64 位操作系统并且仍然出现异常,请转到 Project properties -> Build 选项卡并确保将 x64 设置为平台目标。只需如下:

    第二

    由于您的应用将包含更大的数据,我们强烈建议您使用 MVVM 模式。
    因为 MVVM 模式有助于将应用程序的业务和表示逻辑与其 UI 清晰分离。它还可以极大地提高代码重用机会,让我们和 UI 设计师在开发应用程序的各个部分时更轻松地协作。

    【讨论】:

    • 感谢您的回复。我尝试显示列表视图的方式是否正确?