2016-11-17 123 views
1

我有这个在我的视图模型:叩击手势手势识别器无法正常工作

public class MyClass: INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    int taps = 0; 
    ICommand tapCommand; 

    public MyClass() 
    { 
     tapCommand = new Command(OnTapped); 
    } 

    public ICommand TapCommand 
    { 
     get { return tapCommand; } 
    } 

    void OnTapped(object s) 
    { 
     taps++; 
     Debug.WriteLine("parameter: " + s); 
    } 
} 

,这在XAML:

<Image Source="delete.jpg" HeightRequest="20" WidthRequest="20"> 
    <Image.GestureRecognizers> 
     <TapGestureRecognizer 
      Command="{Binding TapCommand}" 
      CommandParameter="Image1" /> 
    </Image.GestureRecognizers> 
</Image> 

但单击图像时没有出现在输出日志。我错过了什么?

注1:我已经按照指导here

注2:我调试Android设备

更新1:全XAML here

+0

listview在哪里? Image是DataTemplate的一部分吗?你能提供更多的xaml吗? –

+0

我无法重现这一点。我得到[0:]参数:Image1 –

+0

问题更新与完整的xaml pastebin链接@YuriS – Segamoto

回答

2

您没有提供任何背后的代码,所以我不得不创建我自己的(见下文)。 你如果注释掉ListView控件的IsEnabled =“假”

当您设置Command="{Binding TapCommand}的TapCommand对应列表项的TapCommand,而不是模型本身也救了我15分钟。所以,你有两个选择

  1. 您可以实现单击MyItem
  2. 定义背景图像本身结合(你想要的,因为它使部分代码MyItem类下面评论说,我不认为)。 因此,我们的视图模型可以创建几次 - 我们不希望这样做,所以最好的解决方案是定义视图模型的静态资源,并在页面上的任何地方使用它。 的解决方案是低于(你只需要修改一些命名空间和改变delte.png您delete.jpg):

页XML

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      xmlns:local="clr-namespace:ButtonRendererDemo;assembly=ButtonRendererDemo" 
      x:Class="ButtonRendererDemo.ImageTapComplexPage" 
      BindingContext="{StaticResource viewModel}"> 

     <ContentPage.Resources> 
     <ResourceDictionary> 
      <local:TapComplexViewModel x:Key="viewModel"/> 
     </ResourceDictionary> 
     </ContentPage.Resources> 


<StackLayout> 
    <Label Text="text2" VerticalOptions="Center" HorizontalOptions="Center" /> 
    <StackLayout Padding="0,20,0,20"> 
    <Button Text="text" Clicked="onclick" BackgroundColor="#009688"></Button> 

    </StackLayout> 
    <Label Text="List Type" VerticalOptions="Center" HorizontalOptions="Center" /> 
    <ListView x:Name="lstItems" RowHeight="60" ItemsSource="{Binding Items}" > <!--IsEnabled="False"--> 
     <ListView.ItemTemplate> 
     <DataTemplate> 
      <ViewCell> 
      <StackLayout Orientation="Horizontal" HorizontalOptions="Fill" Padding="0,2,0,2"> 
       <StackLayout Padding="5,5,5,5"> 
       <Image Source="{Binding source}" HorizontalOptions="End" HeightRequest="40" WidthRequest="40" /> 
       </StackLayout> 
       <StackLayout Orientation="Vertical" Spacing="1"> 
       <Label Text = "{Binding name}" HeightRequest="20" FontAttributes="Bold"/> 
       <Label Text = "{Binding data, StringFormat='{0:F0}'}" /> 
       </StackLayout> 
       <StackLayout HorizontalOptions="EndAndExpand" Padding="0,0,15,0" Orientation="Horizontal"> 
       <Image Source="delete.png" HeightRequest="20" WidthRequest="20"> 
        <Image.GestureRecognizers> 
        <!--<TapGestureRecognizer 
         Command="{Binding TapCommand}" 
         CommandParameter="Image1" />--> 
         <TapGestureRecognizer Command="{Binding Source={StaticResource viewModel}, Path=TapCommand}" CommandParameter="{Binding name}" /> 
       </Image.GestureRecognizers> 
       </Image> 
       </StackLayout> 
      </StackLayout> 
      </ViewCell> 
     </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 
    </StackLayout> 
</ContentPage> 

代码背后

namespace ButtonRendererDemo 
{ 
    public partial class ImageTapComplexPage : ContentPage 
    { 
     public ImageTapComplexPage() 
     { 
      InitializeComponent();   
     } 

     void onclick(object sender, EventArgs args) 
     { 

     } 
    } 

    public class TapComplexViewModel : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 
     int taps = 0; 
     ICommand tapCommand; 

     public ObservableCollection<MyItem> Items { get; private set; } 
     public TapComplexViewModel() 
     { 
      Items = new ObservableCollection<MyItem>() 
      { 
       new MyItem { name="First", source="Icon.png", data=0.5f }, 
       new MyItem { name="Second", source="Icon.png", data=0.6f }, 
       new MyItem { name="Third", source="Icon.png", data=0.7f } 
      }; 

      tapCommand = new Command(OnTapped); 
     } 

     public ICommand TapCommand 
     { 
      get { return tapCommand; } 
     } 

     void OnTapped(object s) 
     { 
      taps++; 
      Debug.WriteLine("parameter: " + s); 
     } 



    } 

    public class MyItem 
    { 
     public string name { get; set; } 
     public string source { get; set; } 
     public float data { get; set; } 

     //public ICommand TapCommand 
     //{ 
     // get { return new Command(() => { }); } 
     //} 
    } 
} 

enter image description here

+0

如果你有一个问题如何传递点击到从你的模型页面,你可以创建一个单独的问题,让我知道。我也有这个解决方案。 –

+1

在MyItem中的实现工作,谢谢! – Segamoto

1

在后端的xaml文件确保你设置BindingContext到视图模型:类似这样的:

xaml.cs

public partial class TapInsideFrameXaml : ContentPage 
    { 
     public TapInsideFrameXaml() 
     { 
      InitializeComponent(); 

      // The TapViewModel contains the TapCommand which is wired up in Xaml 
      BindingContext = new TapViewModel(); 
     } 
} 

同时检查:

菜单>工具>选项>调试>常规:

  • 确保 “重定向所有输出窗口的文本即时窗口” 未选中

对项目性质>构建:

  • 配置:调试
  • “定义DEBUG常数” 被选中
  • “定义TRACE常数” 被选中

上的输出窗口:

  • 显示输出:调试
  • 在输出窗口中单击右键并确保检查“程序输出”

还要确保你正在使用F5进行调试而不是Ctrl f5

+0

是的,我有这个! – Segamoto

+0

你尝试添加一个breakpont并查看该命令是否被调用? –

+0

是的,它的工作 – Segamoto

0

你声明了PropertyChangedEvent事件,但你永远不会使用它。试试这个:

public class MyClass: INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    int taps = 0; 
    ICommand tapCommand; 

    public MyClass() 
    { 
     tapCommand = new Command(OnTapped); 
    } 

    public ICommand TapCommand 
    { 
     get { return tapCommand; } 
    } 

    void OnTapped(object s) 
    { 
     taps++; 
     Debug.WriteLine("parameter: " + s); 
     OnPropertyChanged(); 
    } 


    protected virtual void OnPropertyChanged ([CallerMemberName] string propertyName = null) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
      handler (this, new PropertyChangedEventArgs (propertyName)); 
    } 
} 
+0

仍然没有工作 – Segamoto