2017-08-29 37 views
0

我有一個帶有ViewCell的Listview,在這個ViewCell中有3個圖像和3個標籤。爲了處理輕敲事件,我爲每個控件編寫了一個GestureRecognizers。如何在ListView中處理特定控件的事件(Xamarin)

<ListView HasUnevenRows="True" 
      SeparatorColor="White" 
      ItemsSource="{Binding List}" 
      SelectedItem="{Binding SelectedItem, Mode=TwoWay}" 
      ItemSelected="Handle_ItemSelected" 
      ItemTapped="ListView_ItemTapped"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <ViewCell> 
         <StackLayout Spacing="0"> 
          <StackLayout Orientation="Horizontal" Padding="16,8,16,4"> 
           <Image Source="{Binding IconImageSource}" HeightRequest="36" WidthRequest="36"/> 
           <StackLayout HorizontalOptions="StartAndExpand" Padding="8,0,0,0" Spacing="0"> 
            <Label Text="{Binding LocalizedText}" TextColor="White"/> 
            <Label Text="{Binding Value}" TextColor="Gray" FontSize="Small"/> 
           </StackLayout> 
          </StackLayout> 
          <BoxView Color="WhiteSmoke" HeightRequest="1" HorizontalOptions="FillAndExpand" Opacity="0,5" /> 
          <RelativeLayout Padding="0,4,0,4" > 
           <Image Source="ic_ecu_eye" 
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.25}" 
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0, Constant=4}" 
             /> 
           <Label Text="{Binding ViewedCount}" 
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.25, Constant=20}" /> 
           <Image Source="ic_ecu_favorite" 
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.5}" 
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0, Constant=4}"/> 
           <Label Text="{Binding FavoriteCount}" 
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.5, Constant=20}" /> 
           <Image Source="ic_ecu_comment" 
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.75}" 
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0, Constant=4}"> 

            <Image.GestureRecognizers> 
             <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" NumberOfTapsRequired="1"/> 
            </Image.GestureRecognizers> 
           </Image> 
           <Label Text="{Binding CommentsCount}" 
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.75, Constant=20}"> 
            <Label.GestureRecognizers> 
             <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" NumberOfTapsRequired="1"/> 
            </Label.GestureRecognizers> 
           </Label> 
          </RelativeLayout> 
         </StackLayout> 


        </ViewCell> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 

代碼隱藏

async private void TapGestureRecognizer_Tapped(object sender, System.EventArgs e) 
    { 
     // want to get listview item 
    } 

ListView_ItemTapped是處理ListView的敲打事件

async private void ListView_ItemTapped(object sender, ItemTappedEventArgs e) 
    { // easily get the tapped item via e.Item } 

與列表視圖竊聽事件,TapGestureRecognizer_Tapped不能輕易得到,我需要處理一些竊聽項目背後的邏輯。 所以這是我的問題,我怎樣才能得到輕按的項目,如果我點擊喜歡這裏的GestureRecognizer事件方法列表視圖裏的控件

async private void TapGestureRecognizer_Tapped(object sender, System.EventArgs e) 
    { 
     // TODO: 
    } 
+0

如果你想切換到'Command'你可以使用'CommandParameter' –

+0

您必須直接輕擊到你的圖片,然後。或者你可以嘗試帶圖像的按鈕,也可以設置'CommandParameter' – Lee

回答

2

雖然你可以用一個事件做到這一點,我認爲這將是更好使用中的Command屬性執行此操作。我爲你演示了一個示例項目。你可以找到它here

刪除Tapped屬性,並開始使用Command,就像這樣。

<Label.GestureRecognizers> 
    <TapGestureRecognizer Command="{Binding Path=BindingContext.TapCommand, Source={x:Reference Name=ThaPage}" CommandParameter="{Binding .}" /> 
</Label.GestureRecognizers> 

你會注意到Command需要一些工作。這是因爲ListViewBindingContext將是單元格綁定的項目。而您希望命令位於頁面的BindingContext上。這樣做會從「ThaPage」的BindingContext中讀取Command。不要忘記給你的頁面x:Name="ThaPage"屬性。你可以想想一個更好的名字。第二,有CommandParameter。通過插入{Binding .} here. You bind the actual object of the item bound to that單元格。現在

BindingContext,定義Command這樣的:

public Command TapCommand => new Command<Foo>((fooObject) => Tapped(fooObject)); 

private void Tapped(Foo fooObject) 
{ 
    DisplayAlert("Tapped!", fooObject.Bar, "Gotcha"); 
} 

你可以指定你期待什麼類型的對象的角度括號內。你可以放棄它。然後只有一個object會通過,你需要做鑄造。

然後在處理Command的方法中,您將可以使用挖掘對象。這個例子中的對象是Foo

+0

謝謝。當我運行這個例子時,我得到了''''''找不到'xxx.ViewModel'的'Command'屬性。我應該爲TapCommand聲明一個BindableProperty嗎? –

0

傑拉爾德的答案是答案。

BTW,我認爲你可以用

async private void TapGestureRecognizer_Tapped(object sender, System.EventArgs e) 
{ 
    // want to get listview item 
    await Application.Current.MainPage.DisplayAlert("Article", ((YourModel)this.BindingContext).YourField, "Ok"); 

} 

我試圖創建與代碼的ViewCell和它的作品嚐試。我不知道用XAML創建ViewCell是否有問題。

這是我ViewCell的完整代碼

class ListViewTemplateGrid : ViewCell 
{ 
    public ListViewTemplateGrid(){ 

     TapGestureRecognizer tgr = new TapGestureRecognizer(); 
     tgr.Tapped += async (object sender, EventArgs e) => { 

      try { 

       await Application.Current.MainPage.DisplayAlert("Article", ((ListViewModel)this.BindingContext).Description, "Ok"); 

      } 
      catch(Exception ex){ 

       await Application.Current.MainPage.DisplayAlert("Error", ex.Message, "Ok"); 
      } 

     }; 

     Label labelDescription = new Label() {VerticalOptions = LayoutOptions.Center}; 
     labelDescription.SetBinding(Label.TextProperty, "Description"); 
     labelDescription.GestureRecognizers.Add(tgr); 

     Label labelQty = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }; 
     labelQty.SetBinding(Label.TextProperty, "Qty"); 

     Label labelOrdered = new Label() { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }; 
     labelOrdered.SetBinding(Label.TextProperty, "Ordered"); 

     // Add controls to the grid 
     Grid grid = CreateGrid(); 
     grid.Children.Add(labelDescription, 0,1,0,1); 
     grid.Children.Add(SeparatorV(), 1, 2, 0, 1); 
     grid.Children.Add(labelQty, 2, 3, 0, 1); 
     grid.Children.Add(SeparatorV(), 3, 4, 0, 1); 
     grid.Children.Add(labelOrdered, 4, 5, 0, 1); 

     grid.Children.Add(SeparatorH(), 0, 5, 1, 2); 

     this.View = grid; 

    } 
} 
相關問題