首页 > 解决方案 > 将 xaml.cs 后面的代码移动到 xamarin 中的 ViewModel

问题描述

我已经在 xaml.cs 文件中编写了我的背后代码逻辑,现在我想将我的代码从后面的代码移动到 ViewModel。除了代码重构之外,如何做到这一点。

我是 xamarin 的新手

这是我背后的代码

namespace _somename
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class CareingtonFeeSchedule : ContentPage
    {

        private OneDentalFeeScheduleService oneDentalFeeScheduleService;
        private ObservableCollection<ProviderSearchViewModel> _allGroups;
        private ObservableCollection<ProviderSearchViewModel> _expandedGroups;

        protected ObservableCollection<Grouping<string, FeeScheduleItem>> feeScheduleGroups;
        protected ObservableCollection<FeeScheduleItem> feeScheduleItems;

        private readonly AppViewModel AppViewModelInstance;
        private Plugin.Geolocator.Abstractions.Position currentPosition;

        private FeeScheduleModel feeScheduleDataResult;
        public CareingtonFeeSchedule(AppViewModel appViewModel)
        {
            InitializeComponent();

            AppViewModelInstance = appViewModel;

            BindingContext = AppViewModelInstance;
            AppViewModelInstance.IsActivityLoading = true;
            LoadFeeeSchedule();
        }

        private void HeaderTapped(object sender, EventArgs args)
        {
            int selectedIndex = _expandedGroups.IndexOf(
                ((ProviderSearchViewModel)((Button)sender).CommandParameter));
            _allGroups[selectedIndex].Expanded = !_allGroups[selectedIndex].Expanded;
            UpdateListContent();
        }

        async Task OnHomeFeeScheduleTapped_TappedAsync(object sender, EventArgs args)
        {
            await Navigation.PushAsync(new AccLandPage(AppViewModelInstance));
        }

        private void ProviderBar_TextChanged(object sender, TextChangedEventArgs e)
        {
            var keyword = ProviderSearchBar.Text;

            GroupedView.ItemsSource =
                                _expandedGroups.Where(s =>
                s.Title.ToLower().Contains(keyword.ToLower()));
        }

        private void UpdateListContent()
        {
            _expandedGroups = new ObservableCollection<ProviderSearchViewModel>();
            foreach (ProviderSearchViewModel group in _allGroups)
            {
                ProviderSearchViewModel newGroup = new ProviderSearchViewModel(group.Title, group.ShortName, group.Expanded);
                if (group.Expanded)
                {
                    foreach (Plan plan in group)
                    {
                        newGroup.Add(plan);
                    }
                }
                _expandedGroups.Add(newGroup);
            }
            GroupedView.ItemsSource = _expandedGroups;
        }

        public FeeScheduleModel FeeScheduleDataResult
        {
            protected set
            {
                feeScheduleDataResult = value;

                OnPropertyChanged(nameof(FeeScheduleDataResult));
            }

            get => feeScheduleDataResult;
        }

        protected int feeScheduleCount;
        public int FeeScheduleCount => feeScheduleCount;

        private async Task<bool> LoadFeeeSchedule()
        {

            try
            {
                if (oneDentalFeeScheduleService == null)
                {
                    oneDentalFeeScheduleService = new OneDentalFeeScheduleService("1dental.com");
                }
                var feeSchedRes = await oneDentalFeeScheduleService.GetFeeScheduleAsync(AppViewModelInstance.ZipCode, string.Empty, CancellationToken.None);

                if (feeSchedRes?.Schedule?.Count > 0)
                {

                    ConvertFeeScheuleDict(feeSchedRes.Schedule);
                }
                else FeeScheduleDataResult = null;

                return true;

            }
            catch (Exception eX)
            {
               with the fee schedule lookup: \n{eX.Message}", "OK");


                return false;
            }
            finally
            {

                AppViewModelInstance.IsActivityLoading = false;
                actInd.IsRunning = false;
            }
        }

        private void ConvertFeeScheuleDict(Dictionary<string, List<FeeScheduleItem>> feesche)
        {

            ObservableCollection<ProviderSearchViewModel> list = new ObservableCollection<ProviderSearchViewModel>();

            ProviderSearchViewModel psm = null;

            foreach (var item in feesche)
            {
                psm = new ProviderSearchViewModel(item.Key, "");

                foreach (var valitem in item.Value)
                {
                    Plan p = new Plan();
                    p.Code = valitem.Code;
                    p.CostDisplay = valitem.CostDisplay;
                    p.Description = valitem.ProcedureSecondary;
                    p.Name = valitem.Procedure;

                    psm.Add(p);
                }

                list.Add(psm);
            }

            _allGroups = list;

            UpdateListContent();

        }

        private async void GetZipCode()
        {
            try
            {   

                if (AppViewModelInstance.UserPosition == null)
                {
                    try
                    {
                        var hasPermission = await Utils.CheckPermissions(Permission.Location);
                        if (!hasPermission)
                        {

                            await Navigation.PushAsync(new MainScreen());

                            return;
                        }
                    }
                    catch (Exception ex)
                    {

                        Debug.WriteLine($"Exception occurred while looking permission during Appearing event: {ex}");
                    }                                      

                    var locator = CrossGeolocator.Current;


                    currentPosition = await locator.GetPositionAsync(new TimeSpan(0, 0, 0, 10, 0));

                    var addressList = await locator.GetAddressesForPositionAsync(currentPosition, null);

                    AppViewModelInstance.UserPosition = currentPosition;


                    foreach (var item in addressList)
                    {
                        AppViewModelInstance.ZipCode = item.PostalCode;
                        ZipCodeEntry.Text = item.PostalCode;
                        break;
                    }
                }
                else
                {
                    var locator = CrossGeolocator.Current;
                    currentPosition = AppViewModelInstance.UserPosition;
                    var addressList = await locator.GetAddressesForPositionAsync(currentPosition, null);
                    foreach (var item in addressList)
                    {
                        AppViewModelInstance.ZipCode = item.PostalCode;
                        ZipCodeEntry.Text = item.PostalCode;
                        break;
                    }
                }                

                LoadFeeeSchedule();
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Exception occurred while looking up location during Appearing event: {ex}");
            }

        }

        private void ZipCodeEntry_Complete(object sender, EventArgs e)
        {
            if (sender != null)
            {
                AppViewModelInstance.ZipCode = ((Entry)sender).Text;
            }
        }

        private void ZipCodeEntry_Changed(object sender, EventArgs e)
        {
            if (sender != null)
            {
                string _text = ((Entry)sender).Text;      //Get Current Text

                if (_text.Length > 5)       //If it is more than your character restriction
                {
                    _text = _text.Remove(_text.Length - 1);  // Remove Last character

                    ZipCodeEntry.Text = _text;        //Set the Old value               
                }

                if (_text.Length == 5)
                {
                    AppViewModelInstance.ZipCode = _text;
                    LoadFeeeSchedule();   
                }
            }
        }

        public bool CanRefreshExecute(string tempVal = null)
        {
            if (AppViewModelInstance.IsRefreshing) return false;
            var valToCheck = tempVal ?? AppViewModelInstance.ZipCode;

            if (string.IsNullOrEmpty(valToCheck) || string.IsNullOrWhiteSpace(valToCheck)) return false;

            bool isDigitString = true;
            foreach (var c in valToCheck)
            {
                if (char.IsDigit(c)) continue;
                isDigitString = false;
            }

            if (isDigitString) AppViewModelInstance.ZipCode = valToCheck;

            return isDigitString;
        }

        private void GroupedView_ItemTapped(object sender, ItemTappedEventArgs e)
        {

        }               
    }
}

标签: c#xamarindata-bindingviewmodelcode-behind

解决方案


只需将您的代码导出到视图模型并将视图模型设置为页面的绑定上下文。例如在构造函数中:

//In the code behind
PageViewModel viewModel;

public Page()
{
    this.BindingContext = viewModel = new PageViewModel();

//...
}

ViewModel 应该实现 INotifyPropertyChanged。

(由事件触发的函数必须留在代码中,并通过 ViewModel 属性访问视图模型)


推荐阅读