Подтвердить что ты не робот

Xamarin Forms ListView ItemTapped/ItemSelected Command Binding на XAML

Как связать объект ICommand с моей ViewModel (в настоящее время в BindingContext) с ItemTapped или ItemSelected из ListView в XAML?

Это простая задача при использовании кнопки, я просто устанавливаю Command = "MyViewModelCommand", и все работает.

4b9b3361

Ответ 1

Я не уверен, почему вам нужно предоставить событие Item Selected или Item Tapped на вашей странице, когда вы можете напрямую получить выбранный/обработанный объект непосредственно в ViewModel:

Я думаю, что вы связали список с ниже типов кода

<ListView ItemsSource="{Binding PermitDetails}" 
SelectedItem="{Binding objItemSelected, Mode=TwoWay}" x:Name="lst" 
RowHeight="35" HorizontalOptions="FillAndExpand" 
VerticalOptions="Fill">

И в модели просмотра, которую вы связываете со страницей, вы должны определить свойство objItemSelected, как указано ниже в коде

private Permit _ItemSelected;
public Permit objItemSelected {
    get {
        return _ItemSelected;
    }
    set {
        if (_ItemSelected != value) {
            _ItemSelected = value;
            OnPropertyChanged ("ItemSelected");
        }
    }
}

И если вы хотите выполнить какие-либо дополнительные функции, например, перейти на страницу с подробными сведениями, вы можете сделать это из свойства set после выполнения инструкции OnPropertyChanged.

Надеюсь, это поможет!

Ответ 2

Мой сценарий - это клавиатура, а изображения - это кнопки, и когда один нажат, соответствующий символ отображается на ярлыке.

Итак..

Предположим, что у вас есть контроль (ключ 1):

<Image  x:Name="imgKey1"
        Source="key1.png"
        Aspect="AspectFit" />

И вы хотите, чтобы изображение было задействовано для запуска команды из объекта "viewModel". Мой "viewModel" имеет свойство next:

public ICommand AddCharCommand { protected set; get; }

где в моем классе (модель представления) у меня есть:

  this.AddCharCommand = new Command<string>((key) =>
            {
                // Add the key to the input string.
                this.InputString += key;
            });

"InputString" - это свойство строки...

Итак, для привязки вида и режима я делаю следующее:

  imgKey1.GestureRecognizers.Add(new TapGestureRecognizer
        {
            Command = viewModel.AddCharCommand,
            CommandParameter = "1",
        });

Я надеюсь, что я помогу вам, если кому-то что-то понадобится, и я могу помочь; я здесь... и там. JJ

В XAML 17-11-14

      <Image  Source="n1normal.png"
              Aspect="AspectFit" >
        <Image.GestureRecognizers>
          <TapGestureRecognizer
            Command="{Binding AddCharCommand}"
            CommandParameter ="1"/>
        </Image.GestureRecognizers>
      </Image>

//-OR-

        <Image Source="magnifyglass.png"
               Aspect="AspectFit"
               HorizontalOptions="End">
          <Image.GestureRecognizers>
            <TapGestureRecognizer Tapped="Search"/>
          </Image.GestureRecognizers>  
        </Image>

//And for the Search create in your ViewModel

 private void Search(object sender, EventArgs e)
 {
      //Your code here
 }

Ответ 3

Я использовал подход привязки выбранного элемента к модели представления, но это, как правило, вызывало проблемы с фильтрацией программных изменений и действий пользователя. Мой личный фаворит - это прикрепленное свойство.

public static readonly BindableProperty ListItemTappedCommandProperty = BindableProperty.CreateAttached<AttachedProperties, ICommand>(
    staticgetter: o => (ICommand) o.GetValue(ListItemTappedCommandProperty), 
    defaultValue: default(ICommand),
    propertyChanged: (o, old, @new) =>
    {
        var lv = o as ListView;
        if (lv == null) return;

        lv.ItemTapped -= ListView_ItemTapped;
        lv.ItemTapped += ListView_ItemTapped;
    });

private static void ListView_ItemTapped(object sender, object item)
{
    var lv = sender as ListView;

    var command = (ICommand) lv?.GetValue(ListItemTappedCommandProperty);
    if (command == null) return;

    if (command.CanExecute(item))
        command.Execute(item);
}

... и затем установите в ListView с помощью:

controls:AttachedProperties.ListItemTappedCommand="{Binding ItemSelectedCommand}"

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

Ответ 4

Почему бы не связать атрибут selectedItem вашего списка со свойством viewModel (скажем, свойство selectedItem); затем в установщике для свойства selectedItem в viewModel вы выполняете свою команду.

Ответ 5

Это старый вопрос, и, возможно, это довольно недавняя разработка, но вы можете использовать Поведения на любом элементе управления для преобразования события в ICommand.

Пример...

<ListView ItemsSource="{Binding Tags}"
            SelectedItem="{Binding SelectedTag}">
    <ListView.Behaviors>
        <behaviors:EventHandlerBehavior EventName="ItemSelected">
            <behaviors:InvokeCommandAction Command="{Binding SelectedTagChanged}" />
        </behaviors:EventHandlerBehavior>
    </ListView.Behaviors>
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ContentView Padding="8">
                    <Label Text="{Binding DisplayValue}" />
                </ContentView>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

В этом примере событие ItemSelected будет сопоставлено с командой SelectedTagChanged в модели представления, которая выглядит следующим образом...

public Command SelectedTagChanged
{
    get
    {
        return new Command(row =>
        {
            // do something
        });
    }
}