MVVM вызывает асинхронный метод при изменении выбора - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть простой список с выбранным элементом, привязанным к свойству ViewModel

<ListBox SelectedItem="{Binding SelectedItem, Mode=TwoWay}">

, и у меня есть асинхронный метод, который я хочу запустить при изменении выбора

async Task foo();

Iмог бы поместить этот вызов в сеттер для SelectedItem, но для меня это запах кода.

public object SelectedItem
{
    get{...}
    set
    {
         foo(); //Compiler warning and blocks UI
         ...
    }
}

Task.Run внутри набора является опцией, но все равно выглядит плохо для меня, и исключение, выданное foo, будет опухшим

Код позади события SelectionChanged может быть другой опциейно какой самый MVVM способ решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Я бы настроил обработчик событий.

что-то вроде

 public class ViewModel:INotifyPropertyChanged
{

    public ViewModel()
    {
        PropertyChanged += SelectedItemChanged;
    }

    private async void SelectedItemChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(SelectedItem))
        {
            await Foo();
        }
    }

    public Task Foo()
    {
        return Task.Run(() =>
        {
            var a = "B";
        });
    }

    private object _selectedItem;

    public object SelectedItem
    {
        get=> _selectedItem;
        set
        {
            if (value != _selectedItem)
            {
                _selectedItem = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
0 голосов
/ 21 сентября 2018

Если вы хотите использовать подход с нулевым кодом, вот что я бы сделал.

Преобразование события SelectedItemChanged в команду с помощью Interaction.

Вот код для преобразованиясобытие для команды

   <i:Interaction.Triggers>
        <i:EventTrigger EventName="SomeEvent">
            <i:InvokeCommandAction Command="{Binding Path=SomeCommand, Mode=OneWay}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

Ваша команда в модели представления затем заблокирует пользовательский интерфейс и вызовет асинхронную функцию.

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