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

#c# #mvvm #xamarin.forms

#c# #mvvm #xamarin.forms

Вопрос:

я пытаюсь включить запись.Завершено преобразование события в команду с использованием MVVM. Я нашел эту статью: https://devblogs.microsoft.com/xamarin/turn-events-into-commands-behaviors / и попытался сделать что-то подобное, но в файле Behavior.cs в Bindable_Completed команда функции всегда передается как null, я не понимаю почему, пожалуйста, помогите. Код файла поведения:

 public class EntryCompletedBehavior : Behavior<Entry>
{
    protected override void OnAttachedTo(Entry bindable)
    {
        base.OnAttachedTo(bindable);

        AssociatedObject = bindable;

        bindable.BindingContextChanged  = Bindable_BindingContextChanged;
        bindable.Completed  = Bindable_Completed;
    }
    protected override void OnDetachingFrom(Entry bindable)
    {
        base.OnDetachingFrom(bindable);

        bindable.BindingContextChanged -= Bindable_BindingContextChanged;
        bindable.Completed -= Bindable_Completed;

        AssociatedObject = null;
    }

    private void Bindable_BindingContextChanged(object sender, System.EventArgs e)
    {
        OnBindingContextChanged();
    }
    private void Bindable_Completed(object sender, System.EventArgs e)
    {
        if (Command == null) return;

        //object parameter = Converter.Convert(e, typeof(object), null, null);
        if (Command.CanExecute(e))
        {
            Command.Execute(e);
        }

    }

    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();
        BindingContext = AssociatedObject.BindingContext;
    }

    public Entry AssociatedObject { get; private set; }
    public static readonly BindableProperty CommandProperty =
            BindableProperty.Create("Command", typeof(ICommand), typeof(EntryCompletedBehavior), null);
    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }
}
  

Код Xaml:

     <Grid BindableLayout.ItemsSource="{Binding ActualValues}"
          Grid.Column="0"
          Grid.ColumnSpan="2"
          Grid.Row="0">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <Frame Margin="{Binding Margin}">
                    <Entry TabIndex="{Binding Id}"
                           Text="{Binding Value}"
                           Placeholder="{Binding Placeholder}"
                           Style="{StaticResource EntryStyle}">
                        <Entry.Behaviors>
                            <behaviors:EntryCompletedBehavior Command="{Binding EntryCompletedCommand}"/> 
                        </Entry.Behaviors>
                    </Entry>
                </Frame>
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </Grid>
  

Код виртуальной машины:

 public SaveMeasurementViewModel()
        {
            SaveMeasurmentCommand = new Command(async () => await SaveMeasurment(), () => !IsBusy);
            ClearMeasurmentCommand = new Command(ClearMeasurment);
            EntryCompletedCommand = new Command(_ => EntryCompleted(_));

            ActualValues = new ObservableCollection<MyEntry>() { };
            for (int index = 0; index < numberOfMeasurments; index  )
            {
                RegisterObserver(new MyEntry(index, this));
            }
        }
  public System.Windows.Input.ICommand EntryCompletedCommand { get; protected set; }
    void EntryCompleted(object param)
    {
        Application.Current.MainPage.DisplayAlert("Save", "Measurment data has been saved", "OK");
    }
  

Комментарии:

1. Если Command равно null, то Command ничего не было назначено. Пожалуйста, поделитесь XAML, где вы пытаетесь использовать это поведение

2. <Запись. Поведение> <поведения:Команда Entry completedbehavior=»{Привязка Entry completedcommand}»/> </Запись. Поведение>

3. Это единственное место, которое вы используете EntryCompletedBehavior ? Произошел сбой привязки: есть ли что-нибудь в окне вывода?

4. Ах, только что видел вашу правку. Вы уверены, что DataContext было правильно установлено в тот момент, когда вы это делаете {Binding EntryCompletedCommand} ? Это будет зависеть от BindableLayout.ItemsSource , и это может не соответствовать вашим ожиданиям. Опять же, в окне вывода должны быть ошибки привязки, если здесь что-то пошло не так

5. да, возможно, xaml пытается получить EntryCompletedCommand как свойство ActualValues, что неверно

Ответ №1:

Как сказал canton7, эта проблема возникла из-за BindableLayout .ItemsSource, я пытался найти свойство не во всем классе виртуальной машины, а в указанном ItemSource. Я проверил привязку этой команды за пределами BindableLayout.ItemsSource, и это сработало нормально.