web-dev-qa-db-ja.com

Xamarin Forms ListView ItemTapped / ItemSelectedコマンドバインディングXAML

ViewModel(現在BindingContextにある)からICommandオブジェクトをXAMLのListViewにあるItemTappedまたはItemSelectedにバインドするにはどうすればよいですか?

これは、ボタンを使用する場合の単純なタスクです。Command= "MyViewModelCommand"を設定するだけで、すべてが機能します。

18
MarcioGomes

ViewModelで直接選択/タップされたオブジェクトを直接取得できる場合、ページでItem SelectedまたはItem Tappedイベントを提供する必要がある理由はわかりません。

リストビューを以下のタイプのコードにバインドしていると思います

<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");
        }
    }
}

また、詳細ページへの移動などの追加機能を実行する場合は、OnPropertyChangedステートメントの実行後にsetプロパティから実行できます。

お役に立てれば!

25
Nirav Mehta

以前は、選択したアイテムをビューモデルにバインドするアプローチを採用していましたが、プログラムによる変更とユーザーアクションのフィルタリングに問題が生じる傾向がありました。私の個人的なお気に入りは添付プロパティです。

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}"

イベント名を取得してより一般的に適用するためにこれを拡張することも可能ですが、それは別の時間の演習です。

3
Adam Hewitt

私のシナリオはキーパッドであり、画像はボタンであり、クリックすると関連する文字がラベルに表示されます。

そう..

あなたがフォローコントロール(キー1)を持っているとしましょう:

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

そして、「viewModel」オブジェクトからコマンドをトリガーするために画像がタップされたときに必要です。私の「viewModel」には次のプロパティがあります。

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
JohnnyJaxs

リストビューのselectedItem属性をviewModelプロパティ(「selectedItem」プロパティと言う)にバインドしないのはなぜですか。次に、viewModelの 'selectedItem'プロパティのセッターでコマンドを実行します。

0
Madol

これは古い質問です。これはかなり最近の開発かもしれませんが、イベントをICommandに変換するには、任意のコントロールのBehaviorsを使用できます。

例...

<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(() =>
        {
            // do something
        });
    }
}
0
John Livermore