【问题标题】:Xamarin Forms ListView ItemTapped/ItemSelected Command Binding on XAMLXamarin 表单 ListView ItemTapped/ItemSelected 命令绑定在 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)中,我可以将事件直接绑定到视图模型

标签: c# mvvm binding xamarin


【解决方案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 你能帮我解决我的问题吗stackoverflow.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 中发布解决方案...如果您还没有找到它。
    猜你喜欢
    • 2016-09-02
    • 2017-04-16
    • 2018-03-10
    • 2017-01-15
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 2016-10-10
    • 2017-07-22
    相关资源
    最近更新 更多