Xamarin 表单 ListView ItemTapped/ItemSelected 命令绑定在 XAML

Posted

技术标签:

【中文标题】Xamarin 表单 ListView ItemTapped/ItemSelected 命令绑定在 XAML【英文标题】:Xamarin Forms ListView ItemTapped/ItemSelected Command Binding on XAML 【发布时间】:2014-09-07 16:51:02 【问题描述】:

如何将我的 ViewModel(当前位于 BindingContext)中的 ICommand 对象绑定到 XAML 中 ListView 中的 ItemTapped 或 ItemSelected?

使用 Button 时这是一项简单的任务,我只需设置 Command="MyViewModelCommand" 即可。

【问题讨论】:

没有办法将 ListView 的 SelectedItem 绑定到 ViewModel 中的属性吗?这就是您通常在其他基于 XAML 的框架(例如 WPF)中所做的事情。我还没有机会接触 Xamarin.Forms 哈哈 是的...我可以轻松地绑定属性,但命令看起来有点难。我可以绑定 SelectedItem 属性,但找不到绑定“SelectedItemChanged”事件的方法。 通常我会按照后面的代码获取数据,获取所选项目并将其传递给 ViewModel,就像这样 ListView ls = new ListView (); ls.ItemSelected += (对象发送者,SelectedItemChangedEventArgs e) => var param1 = e.SelectedItem; var currentVm = this.BindingContext as YourViewModel; currentVm.MethodName(param1); ; 嗨 KirtiSagar,我和你一样...我正在使用后面的代码来处理 SelectedItemChange 事件,但在 XAML(WPF 或 Windows Phone)中,我可以将事件直接绑定到视图模型 【参考方案1】:

这是一个老问题,也许这是一个相当新的发展,但您可以使用任何控件上的行为将事件转换为 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
        );
    

【讨论】:

这是最有希望的答案,但您的演示并未显示如何处理 ItemSelected 的参数(对象和 SelectedItemChangedEventArgs)。用这种方法处理这些参数是否可行? 只需添加参数(我更改了上面的帖子以显示正在使用的行变量)。 row 是一个对象,但您可以将其转换为正确的模型(用于显示列表项的模型)。 @JohnLivermore 你能帮我解决我的问题吗***.com/questions/60740617/…【参考方案2】:

为什么不将列表视图的 selectedItem 属性绑定到 viewModel 属性(假设是“selectedItem”属性);然后在 viewModel 中的“selectedItem”属性的设置器上执行命令。

【讨论】:

我在那篇文章中没有看到任何 cmets。此外,当您提供链接时,最好包含其中的实际引用。【参考方案3】:

当您可以直接在 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 属性中执行此操作。

希望这会有所帮助!

【讨论】:

嗨 Nirav,我需要在 SelectedItem 事件上触发 VM 命令,不仅要将所选项目值发送到 VM。 我明白你在做什么。非常聪明。使用可观察的属性设置器作为命令事件处理程序。好的。这得到了我的投票。 与经典的 SelectedItem 事件方法相比,这是一种让选择变得容易并且适用于所有平台的好方法! 我将我的 ItemSource 设置为我的列表并将 'objItemSelected' 设置为我的班级,但我收到此错误:无法将类型为 'Xamarin.Forms.Xaml.ElementNode' 的对象转换为类型 'Xamarin.Forms .Xaml.ValueNode' 发现了我的问题。我有 ItemSelected 而不是 SelectedItem!【参考方案4】:

我曾经采用将选定项绑定到视图模型的方法,但这往往会导致过滤掉程序更改与用户操作之间的问题。我个人最喜欢的是附属物。

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"

这甚至可以扩展到获取事件名称并更普遍地应用,但这是另一个练习。

【讨论】:

【参考方案5】:

我的场景是一个键盘,图像是按钮,当点击一个按钮时,相关字符会显示在标签中。

所以..

假设您有跟随控制(键 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
 

【讨论】:

您好,此解决方案在以编程方式绑定命令时效果很好,但您知道如何在 XAML 中进行此绑定吗? 我认为它现在可以在 WinPhone 上运行。如果 ItemSelected 或 ItemTapped 事件已绑定到 ListView。因为我有问题 "MarcioGomes" 抱歉耽搁了。我将在 XAML 中发布解决方案...如果您还没有找到它。

以上是关于Xamarin 表单 ListView ItemTapped/ItemSelected 命令绑定在 XAML的主要内容,如果未能解决你的问题,请参考以下文章

WillEnterForeground 上的 Xamarin 表单更新 ListView

Xamarin 表单中的可扩展 ListView

如何知道 ListView 中修改了哪个 Xamarin 表单条目?

ListView 内的 Xamarin 表单按钮命令绑定

更新 ObservableCollection 无法正确更新 Xamarin 表单中的 ListView

Xamarin 表单从 listview 绑定到 viewmodel