【问题标题】:MVVM - How ListView ItemClick Execute RelayCommand with BindigMVVM - ListView ItemClick 如何使用 Bindig 执行 RelayCommand
【发布时间】:2013-10-28 15:48:10
【问题描述】:

我想在我的列表视图中添加一个命令。单击一个项目时,我想执行我的relayCommand。 现在我有了这些解决方案,它可以工作,但我认为它不是 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.Win8 GalaSoft.MvvmLight.Win8

你能给我建议一个解决方案吗?

【问题讨论】:

    标签: c# xaml data-binding mvvm windows-8


    【解决方案1】:

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

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

    我相信您已经将这种行为作为您拥有的 mvvmlight extras dll 的一部分。

    【讨论】:

      【解决方案2】:

      这是一个工作示例:

      <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

      【讨论】:

        【解决方案3】:

        对于遇到同样问题的朋友,我想说的是,还有一个办法:
        您可以为 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>
        

        然后你可以在页面的 ViewModel 中定义你的命令

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

        【讨论】:

          猜你喜欢
          • 2017-03-11
          • 2018-12-27
          • 2017-10-11
          • 1970-01-01
          • 2011-10-08
          • 2013-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多