#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, и это сработало нормально.