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
你能向我提出一个解决方案吗?
这是一个工作示例:
<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 额外内容的一部分。