簡體   English   中英

Xamarin - 將選取器綁定到 MVVM 命令

[英]Xamarin - Binding a Picker to MVVM command

我正在嘗試在我的 Xamarin 項目中使用 MVVM 架構,但我還不太了解它。

我有兩個實體CrCountryCrCity ,我希望用戶能夠選擇一個國家,然后根據該國家選擇一個城市。 在用戶選擇一個國家之前,我還希望城市的選擇器“不可用”。

為此,我需要知道在我的 Picker 上選擇的項目,以便我可以訪問我的數據庫並傳遞該值。 我怎樣才能做到這一點?

編輯:

它現在可以與我所擁有的一起使用,唯一不起作用的是我的城市選擇器上的IsEnabled屬性。 正如我所說,我希望在選擇一個國家之前禁用城市選擇器。 我不能使用SelectedIndex代替SelectedItem ,因為我的CrCountry實體有一個字符串作為 id,我需要獲取所選項目以按國家/地區過濾城市。 這就是我所擁有的:

我的視圖模型

public class InvoiceDataViewModel : BindableObject
    {
        public InvoiceDataViewModel()
        {
            GetCountries();

        }

        private ApiService _apiService = new ApiService();
        private List<CrCountry> _countries;
        private List<CrCity> _cities;

        public List<CrCountry> Countries
        {
            get => _countries;
            set
            {
                _countries = value;
                OnPropertyChanged();
            }
        }

        public List<CrCity> Cities
        {
            get => _cities;
            set
            {
                _cities = value;
                OnPropertyChanged();

            }
        }

        private CrCountry _selectedCountry;
        public CrCountry SelectedCountry
        {
            get => _selectedCountry;
            set
            {
                _selectedCountry = value;
                OnPropertyChanged();
                UpdateCitiesList();
            }
        }

        private CrCity _selectedCity;
        public CrCity SelectedCity
        {
            get => _selectedCity;
            set
            {
                _selectedCity = value;
                OnPropertyChanged();
            }
        }

        private async void GetCountries()
        {
            // call database here
            var url = string.Concat(Constants.UrlCountry, "?PageSize=", 249);

            var countries = await _apiService.GetCountries(url, CurrentPropertiesService.GetToken());

            Countries = countries.Data;
        }

        private async void UpdateCitiesList()
        {
            var adios = _selectedCountry;

            if(_selectedCountry != null)
            {
                var url = string.Concat(Constants.UrlCity, "?IdCountry=", _selectedCountry.IdCountry,"&PageSize=",120);

                var cities = await _apiService.GetCitiesByCountry(url, CurrentPropertiesService.GetToken());

                Cities = cities.Data;
            }

           
        }

我的查看內容頁面上的我的選擇器

<StackLayout Grid.Column="0" Grid.Row="3" Orientation="Vertical" HorizontalOptions="Fill">
                        <Label>País:</Label>
                            <Picker x:Name="pickerCountry" Title="Seleccione" 
                                    ItemDisplayBinding="{Binding Country}" 
                                    ItemsSource="{Binding Countries}" 
                                    SelectedItem="{Binding SelectedCountry, Mode=TwoWay}"
                                     />
                    </StackLayout>

                    <StackLayout Grid.Column="0" Grid.Row="4" Orientation="Vertical" HorizontalOptions="Fill">
                        <Label>Ciudad:</Label>
                            <Picker x:Name="pickerCity" Title="Seleccione" 
                                ItemsSource="{Binding Cities}" 
                                ItemDisplayBinding="{Binding City}" 
                                SelectedItem="{Binding SelectedCity, Mode=TwoWay}" >
                                <Picker.Triggers>
                                    <DataTrigger TargetType="Picker" Binding="{Binding Source={x:Reference pickerCountry},Path=SelectedItem}" Value="">
                                        <Setter Property="IsEnabled" Value="False"/>
                                    </DataTrigger>
                                </Picker.Triggers>
                            </Picker>
                    </StackLayout>

請幫助我真的迷失了 MVVM 架構。 謝謝。

編輯:

我終於實現了我想要的我使用IsEnabled屬性。 我點擊了這個鏈接:如何從 viewmodel WPF MVVM 中禁用 DatePicker

開始使用 MVVM 有點復雜,但這是我將使用的方法:

啟用/禁用城市:我會使用Xamarin 觸發器

您的代碼將如下所示:

<StackLayout Grid.Column="0" Grid.Row="3" Orientation="Vertical" HorizontalOptions="Fill">
    <Label>Country:</Label>
    <Picker x:Name="pickerCountry" Title="Select one" ItemDisplayBinding="{Binding Name}" ItemsSource="{Binding Countries}" SelectedIndexChanged="PickerCountry_SelectedIndexChanged" SelectedIndex="{Binding SelectedCountryIndex}"/>
</StackLayout>

<StackLayout Grid.Column="0" Grid.Row="4" Orientation="Vertical" HorizontalOptions="Fill">
    <Label>City:</Label>
    <Picker x:Name="pickerCity" Title="Select one" ItemsSource="{Binding .}" ItemDisplayBinding="{Binding City}" SelectedIndexChanged="PickerCity_SelectedIndexChanged">
        <Picker.Triggers>
             <DataTrigger TargetType="Picker" Binding="{Binding Source={x:Reference pickerCountry},Path=SelectedIndex}" Value="-1">
                 <Setter Property="IsEnabled" Value=False/>
             </DataTrigger>
        </Picker.Triggers>
    </Picker>
</StackLayout>

當所選索引為 -1(即默認值且未選擇任何內容)時,它將禁用國家/地區選擇器。

更新城市列表

一旦選擇了一個國家,您就想調用您的數據庫以獲取所有城市。 您將希望綁定到 ViewModel 中的 SelectedIndex 或 SelectedItem。 在本例中,我將使用索引:

private int _selectedCountryIndex
public int SelectedCountryIndex
{
    get => _selectedCountryIndex;
    set
    {
        _selectedCountryIndex = value;
        OnPropertyChanged();
        UpdateCitiesList();
    }
}

當國家索引發生變化時,您調用一個方法 UpdateCititesList() ,您可以在其中更新該國家/地區的城市列表

因此,您可能希望在此處查看加載動畫,以便用戶在檢索城市時無法更改國家/地區,或者您可能希望采用不同的策略。 稍微想一想。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM