为了调用两个不同的业务逻辑:
- 点击 ViewCell 元素本身(在 ListView 内)- 例如导航到不同的页面
- 点击位于给定 ViewCell 元素内的标签元素(可点击标签)——例如删除给定对象或其他内容
我想在页面 ViewModel 中包含完整的“点击”逻辑。
根据 Xamarin 论坛的建议,我可以调用一些逻辑来从单元格中“点击”我的 delete 操作,但是直接在我的数据模型中——这在我的 PoV 中不是好的解决方案,因为我想操纵我的 List 集合(所以最可取的方法是在 ViewModel 页面上使用此逻辑)。
我现在拥有的:
我的页面 View XAML 代码如下:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="App.Views.TestView">
<ContentPage.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<ListView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" ItemsSource="{Binding MyItemsCollection}" SelectedItem="{Binding SelectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<!-- Name Label -->
<Label Text="{Binding Name}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" />
<!-- Delete "Icon" -->
<Label Text="Clickable Label" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnClickableLabel}" CommandParameter="{Binding .}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
我的页面 View C# 代码看起来像(那里没有特定代码,除了将 **BindingContext* 绑定(bind)到页面 ViewModel):
public partial class TestView : ContentPage
{
public TestView()
{
InitializeComponent();
BindingContext = ServiceLocator.Current.GetInstance<TestViewModel>();
}
}
我的页面 ViewModel C# 代码如下:
public class TestViewModel : ViewModelBase
{
public TestViewModel()
{
MyItemsCollection = GetMyItemsCollection();
}
private List<MyItem> GetMyItemsCollection()
{
return new List<MyItem>
{
new MyItem
{
ID = 1L,
Name = "Item 1 Name"
},
new MyItem
{
ID = 2L,
Name = "Item 2 Name"
},
new MyItem
{
ID = 3L,
Name = "Item 3 Name"
}
};
}
private List<MyItem> _myItemsCollection { get; set; }
public List<MyItem> MyItemsCollection
{
get
{
return _myItemsCollection;
}
set
{
_myItemsCollection = value;
RaisePropertyChanged();
}
}
private MyItem _SelectedItem { get; set; }
public MyItem SelectedItem
{
get
{
return _SelectedItem;
}
set
{
if (_SelectedItem != value)
{
_SelectedItem = value;
RaisePropertyChanged();
Debug.WriteLine("SelectedItem: " + _SelectedItem.Name);
}
}
}
private RelayCommand<object> _OnClickableLabel;
public RelayCommand<object> OnClickableLabel
{
get { return _OnClickableLabel ?? (_OnClickableLabel = new RelayCommand<object>((currentObject) => Test(currentObject))); }
}
private void Test(object currentObject)
{
Debug.WriteLine("This should work... but it's not working :(");
}
}
我的数据模型代码如下:
public class MyItem
{
public long ID { get; set; }
public string Name { get; set; }
private RelayCommand<object> _OnClickableLabel;
public RelayCommand<object> OnClickableLabel
{
get { return _OnClickableLabel ?? (_OnClickableLabel = new RelayCommand<object>((currentObject) => Test(currentObject))); }
}
private void Test(object currentObject)
{
Debug.WriteLine("This works... but it's not good idea, to have it here...");
}
}
知道需要更改什么以便直接在我的页面 ViewModel 中调用 OnClickableLabel 吗? 我知道,这是错误的:
<TapGestureRecognizer Command="{Binding OnClickableLabel}" CommandParameter="{Binding .}" />
但不知道是什么:/.
帮助!非常感谢。
最佳答案
好的,我通过扩展 XAML 代码找到了解决方案:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="App.Views.TestView" x:Name="Page">
<ContentPage.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<ListView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" ItemsSource="{Binding MyItemsCollection}" SelectedItem="{Binding SelectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<!-- Name Label -->
<Label Text="{Binding Name}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" />
<!-- Delete "Icon" -->
<Label Text="Clickable Label" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.OnClickableLabel, Source={x:Reference Page}}" CommandParameter="{Binding .}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
在那之后,我在我的页面 ViewModel 中调用了 OnClickableLabel 命令,正如预期的那样:)。
如果有人知道“更好”的解决方案(从 XAML 代码的角度来看更好),我希望看到它;)。
非常感谢大家!
关于c# - 检测点击标签,在 ViewCell 内,在 ListView 内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39033460/