【问题标题】:<ListView> of images - How open URL via TapGestureRecognizer?<ListView> of images - 如何通过 TapGestureRecognizer 打开 URL?
【发布时间】:2017-09-12 09:34:46
【问题描述】:

我们如何打开绑定到图片的 URL(通过 TapGestureRecognizer)?
我的 ListView 的 ItemsSource 是 _partners(List 的类型)。
Partner 类有两个属性 - WebUrl 和 ImageUrl。

<ListView x:Name="partnersListView">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <!--<ImageCell ImageSource="{Binding ImageUrl}" Text="{Binding WebUrl}" />-->
                    <ViewCell>
                        <Image Source="{Binding ImageUrl}">
                            <Image.GestureRecognizers>
                                <TapGestureRecognizer Tapped="Image_TapGestureRecognizer_Tapped" NumberOfTapsRequired="1" CommandParameter="{Binding .}" />
                            </Image.GestureRecognizers>
                        </Image>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>


列表仅显示图像,我希望应用在用户点击图像时导航到网站。但是,以下代码 - 不出所料 - 不起作用。

private void Image_TapGestureRecognizer_Tapped(object sender, System.EventArgs e)
    {
        var tappedMenuItem = sender as MenuItem;

        var partner = tappedMenuItem.CommandParameter as Partner;

        Device.OpenUri(new Uri(partner.WebUrl));
    }

有什么建议吗?

请注意:
我想将 TapGestureRecognizer 保留在 XAML 中 - 而不是在代码隐藏中。
谢谢。

【问题讨论】:

  • 是否有任何理由将其保留在 UI 页面上?您不能将列表视图的 Item Selected 属性绑定到您的 ViewModel 上的道具并对其做出反应以触发 OpenURI?
  • 我没有 ViewModel 页面 - 每个页面上的所有内容都是通过代码隐藏设置的。我是初学者,所以这是我的第一步,所以请放轻松:)
  • 好的,但没有区别......您也可以将 SelectedItem 绑定到您的 View 代码后面的属性。与您对图像源使用绑定的方式相同。
  • @Depechie 能否请您详细说明一下,给我看确切的代码并将其变成答案,以便我接受?漂亮吗?
  • 尝试创建UriBuilder,可能是uri格式不对这里是code-var uri = new UriBuilder(CategoryObject.Website).Uri; Device.OpenUri(uri);

标签: xamarin xamarin.ios xamarin.forms xamarin.android


【解决方案1】:

解决此问题的最佳方法是将ListViewSelectedItem 绑定到页面上的属性。

所以在你看来

<ListView SelectedItem="{Binding SelectedPartner}">
<ListView.ItemTemplate>
    <DataTemplate>
        <ViewCell>
            <Image Source="{Binding ImageUrl}" />
        </ViewCell>
    </DataTemplate>
</ListView.ItemTemplate>

在代码背后

public Partner SelectedPartner
{
    set
    {
        if (value != null)
            Device.OpenUri(new System.Uri(value.WebUrl));
    }
}

【讨论】:

    【解决方案2】:

    列表仅显示图像,我希望应用在用户点击图像时导航到网站。但是,以下代码 - 不出所料 - 不起作用。

    CommandParameter 仅用于Command,您无法从点击事件处理程序中获取它。为了满足您的要求,您可以将TappedCallbackTappedCallbackParameter 一起使用,或者将CommandCommandParameter 一起使用:

    方法一(TapppedCallbackTappedCallbackParameter):

    1. 修改您的Partner 类以保存Action&lt;View,object&gt;

      public class Partner
      {
          public Partner(string weburl, string imageurl)
          {
              this.WebUrl = weburl;
              this.ImageUrl = imageurl;
          }
      
          public Partner(string weburl, string imageurl, Action<View, object> callback) : this(weburl, imageurl)
          {
              this.CallBack = callback;
          }
      
          public Action<View, object> CallBack { get; set; }
      
          public string WebUrl { get; set; }
          public string ImageUrl { get; set; }
      
      }
      
    2. 在您的代码隐藏中,定义一个如下所示的TappedCallback 函数并使用此函数初始化项目源:

      public partial class MainPage : ContentPage
      {
          public MainPage()
          {
              InitializeComponent();
      
              List<Partner> list = new List<Partner>
              {
                  new Partner("http://www.url.com","timg.jpg",TappedCallback),
                  new Partner("http://www.url.com","timg.jpg",TappedCallback),
                  new Partner("http://www.url.com","timg.jpg",TappedCallback),
                  new Partner("http://www.url.com","timg.jpg",TappedCallback),
                  new Partner("http://www.url.com","timg.jpg",TappedCallback),
                  new Partner("http://www.url.com","timg.jpg",TappedCallback)
              };
              partnersListView.ItemsSource = list;
      
          }
      
          private void TappedCallback(View sender,object param)
          {
              var Partner = param as Partner;
      
              Device.OpenUri(new Uri(Partner.WebUrl));
          }
      
      }
      
    3. 在 Xaml 中使用 TappedCallback

      <ListView x:Name="partnersListView">
          <ListView.ItemTemplate>
              <DataTemplate>
                  <!--<ImageCell ImageSource="{Binding ImageUrl}" Text="{Binding WebUrl}" />-->
                  <ViewCell>
                      <Image Source="{Binding ImageUrl}">
                          <Image.GestureRecognizers>
                              <TapGestureRecognizer   TappedCallback="{Binding CallBack}" TappedCallbackParameter="{Binding .}"  NumberOfTapsRequired="1"  />
                          </Image.GestureRecognizers>
                      </Image>
                  </ViewCell>
              </DataTemplate>
          </ListView.ItemTemplate>
      </ListView>
      

    方法二(CommandCommandParameter):

    1. 在您的合作伙伴类和构造函数中定义一个ICommand 以接受ICommand

      public class Partner
      {
          public Partner(string weburl, string imageurl)
          {
              this.WebUrl = weburl;
              this.ImageUrl = imageurl;
          }
      
      
          public Partner(string weburl, string imageurl, ICommand command) : this(weburl, imageurl)
          {
              this.TapCommand = command;
          }
      
          public string WebUrl { get; set; }
          public string ImageUrl { get; set; }
      
          public ICommand TapCommand { get; set; }
      }
      
    2. 创建一个MyCommand类来实现ICommand接口:

      public class MyCommand : ICommand
      {
          public event EventHandler CanExecuteChanged;
      
          public bool CanExecute(object parameter)
          {
              return true;
          }
      
          public void Execute(object parameter)
          {
              var Partner = parameter as Partner;
      
              Device.OpenUri(new Uri(Partner.WebUrl));
          }
      }
      
    3. 在您的代码隐藏中使用新的 MyCommand 对象初始化您的项目源:

      public partial class MainPage : ContentPage
      {
          public MainPage()
          {
              InitializeComponent();
      
              List<Partner> list = new List<Partner>
              {
                  new Partner("http://www.url.com","timg.jpg",new MyCommand()),
                  new Partner("http://www.url.com","timg.jpg",new MyCommand()),
                  new Partner("http://www.url.com","timg.jpg",new MyCommand()),
                  new Partner("http://www.url.com","timg.jpg",new MyCommand()),
                  new Partner("http://www.url.com","timg.jpg",new MyCommand()),
                  new Partner("http://www.url.com","timg.jpg",new MyCommand())
              };
              partnersListView.ItemsSource = list;
          }
      
      }
      
    4. Xaml 中使用Command

      <ListView x:Name="partnersListView">
          <ListView.ItemTemplate>
              <DataTemplate>
                  <!--<ImageCell ImageSource="{Binding ImageUrl}" Text="{Binding WebUrl}" />-->
                  <ViewCell>
                      <Image Source="{Binding ImageUrl}">
                          <Image.GestureRecognizers>
                              <TapGestureRecognizer   Command="{Binding TapCommand}" CommandParameter="{Binding .}"  NumberOfTapsRequired="1"  />
                          </Image.GestureRecognizers>
                      </Image>
                  </ViewCell>
              </DataTemplate>
          </ListView.ItemTemplate>
      </ListView>
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      • 1970-01-01
      相关资源
      最近更新 更多