Как показать выбор выбора перед командой кнопки в MVVM xamarin? - PullRequest
0 голосов
/ 01 марта 2020

У меня есть этот код:

<StackLayout Spacing="20" Padding="15">
<Label Text="Text:" FontSize="Medium" />
<Label Text="{Binding Material.Name}" d:Text="Item name" FontSize="Small"/>
<Label Text="Description:" FontSize="Medium" />
<Label Text="{Binding Material.Description}" d:Text="Item description" FontSize="Small"/>

<Picker x:Name="PocketSelector"
    Title="--Select--"
    ItemsSource="{Binding Pockets}"
    ItemDisplayBinding="{Binding PocketName}"
    SelectedItem="SelectedPocketName"/>

<Button x:Name="AddToButton"
    Text="Add To"
    Command="{Binding AddToPocketCommand}"
    CommandParameter="{Binding SelectedItem, Source={x:Reference PocketSelector}}"/>

Если я нажму AddToButton, тогда команда go в модели представления - все в порядке, шаблон MVVM верен. Но как я могу проверить (в просмотре страницы или в модели представления) выбранный инструмент выбора перед нажатием кнопки? У меня две ситуации: Первый случай - сборщик уже выбран. После этого я нажимаю кнопку и все ок. Secont Case - выбранный элемент выбора еще не выбран. Я нажимаю кнопку и m просто показываю окно выбора . После этого я выбираю элемент и выбираю команду объявления go для просмотра модели (или мне нужна вторая кнопка).

Ответы [ 2 ]

0 голосов
/ 02 марта 2020

Я делаю так (MVVM до свидания)):

        private void Button_Clicked(object sender, EventArgs e)
    {
        // Проверка на наличие орговых предложений

        if(ViewModel.CurrentProduct.HaveOffer)
        {
            if (this.pickerOffer.SelectedIndex >= 0)
            {
                //TODO Тут тоже классный костыль! Четко! Умеете, могете!
                //Button_Clicked вообще из параллельной вселенной сюда пришел
                ViewModel.CurrentOffer = ((ProductOffer)this.pickerOffer.SelectedItem);
                ViewModel.AddToCartCommand.Execute(ViewModel.CurrentProduct);
            }
            else
            {
                // Ничего не выбрано из орговых предложений
                // Необходимо выбраь
                this.pickerOffer.Focus();
            }
        }
        else
        {
            ViewModel.AddToCartCommand.Execute(ViewModel.CurrentProduct);
        }
    }
0 голосов
/ 01 марта 2020

Вы можете реализовать некоторые представления логики c для включения / выключения кнопки всякий раз, когда изменяется выбор сборщика. Это не нарушило бы паттерн MVVM, потому что это просто просмотр логи c.

Но более элегантный способ - это изменить измененную ViewModel, например

public class MainViewModel : ReactiveObject
{
    private Material _material;
    private Pocket _selectedPocket;
    private readonly ObservableCollection<Pocket> _pockets;

    public MainViewModel()
    {
        var canExecuteAddToPocketCommand = this
            .WhenAnyValue( e => e.SelectedPocket )
            .Select( e =>  e != null );

        AddToPocketCommand = ReactiveCommand.CreateFromTask(
            ExecuteAddToPocketCommandAsync,
            canExecuteAddToPocketCommand );

        Material = new Material { Name = "Material Name", Description = "Material Description" };

        _pockets = new ObservableCollection<Pocket>( Enumerable.Range( 1, 10 ).Select( id => new Pocket { PocketName = $"Pocket {id}" } ).ToList() );
        Pockets = new ReadOnlyObservableCollection<Pocket>( _pockets );
    }

    private async Task ExecuteAddToPocketCommandAsync()
    {
        await Task.Delay( 250 );
        SelectedPocket = null;
    }

    public Material Material { get => _material; set => this.RaiseAndSetIfChanged( ref _material, value ); }
    public ICollection<Pocket> Pockets { get; }

    // *** ADDED PROPERTY ***
    public Pocket SelectedPocket { get => _selectedPocket; set => this.RaiseAndSetIfChanged( ref _selectedPocket, value ); }

    public ICommand AddToPocketCommand { get; }
}

Команда сейчас сообщает себе , может ли он быть выполнен или нет, и представление включит / отключит элемент управления для представления этого состояния.

Затем само представление может быть упрощено до:

<StackLayout Padding="15" Spacing="20">
    <Label FontSize="Medium" Text="Text:" />
    <Label
        d:Text="Item name"
        FontSize="Small"
        Text="{Binding Material.Name}" />
    <Label FontSize="Medium" Text="Description:" />
    <Label
        d:Text="Item description"
        FontSize="Small"
        Text="{Binding Material.Description}" />

    <Picker
        Title="--Select--"
        ItemDisplayBinding="{Binding PocketName}"
        ItemsSource="{Binding Pockets}"
        SelectedItem="{Binding SelectedPocket}" />

    <Button Command="{Binding AddToPocketCommand}" Text="Add To" />
</StackLayout>

К вашему сведению: ViewModel использует пакет NuGet ReactiveUI.XamForms

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...