2017-07-06 54 views
-1

我想在點擊列表視圖中的項目後打開另一個視圖。 我曾嘗試添加一個TapGestureRegonizer,甚至添加ViewCell與網格等。這些都似乎工作。我爲標籤添加了一個輕擊手勢,似乎可以正常工作,但對於列表視圖項目,這同樣不起作用。這看起來像列表視圖這樣的簡單問題,但似乎並沒有內置的功能。點擊列表查看項目的手勢

XAML中:

<ListView x:Name="dataList" 
     ItemsSource="{Binding routeLabels}" 
     HasUnevenRows="True" 
     Grid.Row="1" 
     Grid.Column="0" 
     Grid.ColumnSpan="3"> 
</ListView> 

後面的代碼:

var listviewgesture = new TapGestureRecognizer(); 
listviewgesture.SetBinding(TapGestureRecognizer.CommandProperty,"LoadRoutePage"); 
dataList.GestureRecognizers.Add(listviewgesture); 

視圖模型:

public ICommand LoadRoutePage { get; protected set; } 



public DriverDashboardViewModel(INavigation navigation,MessagDatabase database) 
    { 
     this._database = database; 
     this.Navigation = navigation; 
     this.LoadNotifications = new Command(async() => await OpenNotificationsPage()); 
     this.LoadRoutePage = new Command(async() => await OpenRoutePage()); 

    } 

public async Task OpenRoutePage() 
    { 

     await Navigation.PushAsync(new RoutePageView()); 
    } 

只是要清楚的LoadNotifications方法確實在打開頁面的工作,但LoadRoutePage沒有。所以我知道視圖和視圖模型之間存在某種程度的交流。

回答

5

您不應該將TapGestureRecognizer添加到ListView。每個單元格都有處理點擊事件的事件,而GestureRecognizer可能只會混淆關於點擊應該做什麼的ListView。有幾種方法可以解決這個問題。

1的SelectedItem結合

綁定SelectedItem屬性爲ListView和處理你的方法在setter方法調用。

<ListView x:Name="dataList" ItemsSource="{Binding routeLabels}" 
      HasUnevenRows="True" Grid.Row="1" Grid.Column="0"   
      Grid.ColumnSpan="3" SelectedItem="{Binding SelectedItem}"> 
</ListView> 

並在您的視圖模型:

string _selectedItem; 

public string SelectedItem { 
    get {return _selectedItem; } 
    set 
    { 
     _selectedItem = value; 
     // Additional code 
    } 
} 

2.使用內置的事件ItemSelected或ItemTapped

一個ListView有你可以掛鉤一個名爲ItemSelectedItemTapped一些事件。這些可以在代碼隱藏中被捕獲並且可以處理你想要實現的內容。

<ListView x:Name="dataList" ItemsSource="{Binding routeLabels}" 
      HasUnevenRows="True" Grid.Row="1" Grid.Column="0"   
      Grid.ColumnSpan="3" ItemSelected="Handle_ItemSelected" ItemTapped="Handle_ItemTapped"> 
</ListView> 

3.使用事件,命令的行爲

結合由於您使用的ViewModels你最好不希望這些事件,因爲他們在UI端處理。有NuGet軟件包可以將事件轉換爲您可以在視圖模型中處理的Command。以Corcav.Behaviors爲例。

4.創建你自己的

行爲我有一個我經常使用的,看起來像這樣:

public class ListViewSelectedItemBehavior : Behavior<ListView> 
{ 
    public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(ListViewSelectedItemBehavior)); 

    public ICommand Command 
    { 
     get { return (ICommand)GetValue(CommandProperty); } 
     set { SetValue(CommandProperty, value); } 
    } 

    public ListView AssociatedObject { get; private set; } 

    protected override void OnAttachedTo(ListView bindable) 
    { 
     base.OnAttachedTo(bindable); 
     AssociatedObject = bindable; 
     bindable.BindingContextChanged += OnBindingContextChanged; 
     bindable.ItemSelected += OnListViewItemSelected; 
    } 

    protected override void OnDetachingFrom(ListView bindable) 
    { 
     base.OnDetachingFrom(bindable); 
     bindable.BindingContextChanged -= OnBindingContextChanged; 
     bindable.ItemSelected -= OnListViewItemSelected; 
     AssociatedObject = null; 
    } 

    private void OnBindingContextChanged(object sender, EventArgs e) 
    { 
     OnBindingContextChanged(); 
    } 

    private void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e) 
    { 
     if (Command == null) 
      return; 

     if (Command.CanExecute(e.SelectedItem)) 
      Command.Execute(e.SelectedItem); 
    } 

    protected override void OnBindingContextChanged() 
    { 
     base.OnBindingContextChanged(); 
     BindingContext = AssociatedObject.BindingContext; 
    } 
} 

要添加到您的ListView你只是一個行爲添加到它:

<ListView x:Name="dataList" ItemsSource="{Binding routeLabels}" 
      HasUnevenRows="True" Grid.Row="1" Grid.Column="0"   
      Grid.ColumnSpan="3"> 
    <ListView.Behaviors> 
     <behaviors:ListViewSelectedItemBehavior Command="{Binding ItemSelectedCommand}" /> 
    </ListView.Behaviors> 
</ListView> 

在這種情況下ItemSelectedCommand在你的ViewModel一個Command對象。

+0

我會看看這些讓你知道了,謝謝。 – user3355961

+0

在選項一中,您有屬性Route _selectedItem,該類型的Route應該表示什麼?我不知道 – user3355961

+0

這是綁定到您的ListView項目的類型。由於代碼引用包含路由的ListView,我假定綁定到ListView的項目是Route對象。如果它是例如一串字符串將其更改爲「字符串」。 –

0

不知道我是否正確理解了你,但是你試圖在有人點擊listview的元素時發生事件?

如果是這樣你不需要識別你只需要添加ItemTapped在您的XAML:

<ListView x:Name="dataList" 
     ItemsSource="{Binding routeLabels}" 
     HasUnevenRows="True" 
     Grid.Row="1" 
     Grid.Column="0" 
     ItemTapped="Name of event" 
     Grid.ColumnSpan="3"> 
</ListView> 

這會爲你生成一個事件(只是做創建ItemTapped當雙標籤),在這裏你可以放置您的代碼

0

您正在綁定命令而不是事件到「Tapped」事件。嘗試是這樣的:

後面的代碼:

var listviewgesture = new TapGestureRecognizer(); 
listviewgesture.Tapped += Handle_listViewItemTapped; 
dataList.GestureRecognizers.Add(listviewgesture); 

視圖模型:

private void Handle_listViewItemTapped(object sender, EventArgs e) 
{ 
    viewModel.OpenRoutePage(); 
}