MVVM - How ListView ItemClick Execute RelayCommand with Bind

本文关键字:RelayCommand with Bind Execute ItemClick How ListView MVVM | 更新日期: 2023-09-27 18:36:08

我想在我的列表视图中添加一个命令。当一个项目被点击时,我想执行我的中继命令。现在我有了这些解决方案,它有效,但我认为它不是那么 MVVM :)

<ListView ItemsSource="{Binding Taxons}" IsItemClickEnabled="True" ItemClick="ListViewBase_OnItemClick">
       <ListView.ItemTemplate>
            <DataTemplate>
                  <TextBlock Text="{Binding Name}"/>
            </DataTemplate>
       </ListView.ItemTemplate>
</ListView>

代码隐藏:

private void ListViewBase_OnItemClick(object sender, ItemClickEventArgs e)
{
       viewModel.TreeItemSelected.Execute(((Taxon)e.ClickedItem).Name);
}

我想在没有任何代码的情况下使用这种方式,但这是不可能的,因为 VS 告诉我:

<ListView ItemsSource="{Binding Taxons}" IsItemClickEnabled="True" ItemClick="{Binding TreeItemSelected}">
       <ListView.ItemTemplate>
            <DataTemplate>
                  <TextBlock Text="{Binding Name}"/>
            </DataTemplate>
       </ListView.ItemTemplate>
</ListView>

使用以下额外的 dll-s,但如果可能的话,我不想安装任何其他东西。GalaSoft.MvvmLight.Extras.Win8GalaSoft.MvvmLight.Win8

你能向我提出一个解决方案吗?

MVVM - How ListView ItemClick Execute RelayCommand with Bind

这是一个工作示例:

<ListBox x:Name="name_here" 
      ItemsSource="{Binding your_item_source}"
      SelectedItem="{Binding your_selected_item, UpdateSourceTrigger=PropertyChanged}"
     ...
      >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDoubleClick">
            <Command:EventToCommand Command="{Binding your_command_here}" 
                                CommandParameter="{Binding ElementName=name_here, Path=SelectedItem}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListBox>

它利用了 Blend 的交互触发器(您不必安装 blend,如果您没有它,dll 就足够了)。此外,如果您使用的是 CommandParameter ,请将ElementName绑定到控件的名称(在此示例中为 name_here

对于那些有同样问题的人,我想说还有另一种方法:
您可以为 ListView 项定义一个TapGestureRecognizer,并将其绑定到 ViewModel 中的命令,如下所示:

<StackLayout x:Name="StackLayout1" Orientation="Vertical" HorizontalOptions="StartAndExpand" VerticalOptions="FillAndExpand">    
   <StackLayout.BindingContext>
       <viewModels:NotificationsViewModel />
   </StackLayout.BindingContext>
   <ListView ItemsSource="{Binding NotificationsList}">
     <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <StackLayout Orientation="Vertical">  
              <StackLayout.GestureRecognizers>  <!-- here you bind the TAP event to your ViewModel -->
                <TapGestureRecognizer Command="{Binding Path=BindingContext.OnListItemTapped, Source={x:Reference StackLayout1}}" 
                                      CommandParameter="{Binding}"/>
              </StackLayout.GestureRecognizers>
              <RelativeLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                <Image x:Name="IsReadImage" StyleId="IsReadImage" WidthRequest="{StaticResource OptionImageSize}"
                       Source='{Binding IsRead, Converter={StaticResource BooleanToValueConverter}, ConverterParameter="Resources.emailOpenIcon,Resources.emailIcon"}'
                       RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}"
                       RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.8, Constant=0}"></Image>
                <Label Text="{Binding Title}" x:Name="TitleLabel" HorizontalTextAlignment="Start" FontAttributes='{Binding IsRead, Converter={StaticResource BooleanToValueConverter}, ConverterParameter="Bold?!"}'
                       RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=IsReadImage, Property=Width, Constant=5}"
                       RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=IsReadImage, Property=Y, Constant=3}" /></RelativeLayout>
            </StackLayout>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
</StackLayout>

然后,您可以在页面的视图模型中定义命令

public ICommand OnListItemTapped
{
    get
    {
        return new Command<Notification>(item =>
        {
            Debug.WriteLine(item.Title + " Cliked!");
        });
    }
}
您可以通过

两种方式完成此操作。一种是将列表视图 SelectedItem 绑定到视图模型上的属性。 (也许可以将该属性称为 SelectedTaxon),然后在属性 setter 中,您可以对视图模型执行任何您希望的操作。

另一种方式,如果您真的与在视图模型上执行命令有关。您可以使用 mvvmlight EventToCommand 行为。您可以通过Google找到有关该信息,或者在此链接中找到其使用说明。http://adammills.wordpress.com/2011/02/14/eventtocommand-action-mvvm-glue/

我相信您已经将这种行为作为您拥有的 mvvmlight 额外内容的一部分。