单击 collection 项时的操作
Action When Clicking an Item of collection
我有 FlexLayout
用来显示 collection 的内容。我想实现当您单击 collection 的某个元素时执行命令的可能性。我想确保当您单击某个项目时,会加载另一个视图来加载与所选日期相对应的数据。如何让 collection 项对点击做出反应?
<ContentPage.Resources>
<DataTemplate x:Key="ColorItemTemplate">
<Grid Margin="5"
HeightRequest="120"
WidthRequest="105">
<BoxView Color="Azure" />
<Label Text="{Binding Day}"
HorizontalOptions="Center"
VerticalOptions="Center" />
</Grid>
</DataTemplate>
</ContentPage.Resources>
<StackLayout Margin="10">
<Label Text="CollectionView"
FontSize="30"
FontAttributes="Bold"
HorizontalOptions="Center" />
<Label Text="{Binding MyCollection.Count, StringFormat='Count: {0}'}" />
<ScrollView>
<FlexLayout Direction="Row"
Wrap="Wrap"
AlignItems="Center"
AlignContent="Center"
BindableLayout.ItemsSource="{Binding MyCollection}"
BindableLayout.ItemTemplate="{StaticResource ColorItemTemplate}"/>
</ScrollView>
</StackLayout>
but when clicking on an item, where do you want to send data to?
在上面的截图中,你可以在collection中看到20个objects。它们在 class 构造函数中创建,并显示它们的创建时间。
PowerTrainings = new ObservableCollection<PowerTraining>();
for (int i = 0; i < 20; i++)
{
PowerTrainings.Add(new PowerTraining() { DayOfTraining = dateTime });
}
根据我的想法,每次用户(特别是我,因为我自己做)从历史记录中选择特定的一天时,将加载另一个视图,该视图将显示他所做的练习在那一天。但是如何在 XAML 代码中正确实现一个代码,该代码将确定 collection 的这个特定元素被单击(其中显示日期)并将该日期传递给另一个视图,该视图基于属性 DayOfTraining
, 将在这一天用 classes 查询数据库并形成另一个 collection?
If I represent it by analogy with WPF, then I would create a
MouseDoubleClick event and pass the object to another view through the
SelectedIndex property. But in the case of Xamarin, I don't understand
(yet) how everything works.
我可以将你的应用程序部署到我的模拟器,但是当点击一个项目时,你想将数据发送到哪里?
根据场景的不同,在两个视图之间传递数据有多种方式。
一个简单的方法是使用Xamarin.Forms MessagingCenter。
Xamarin.Forms MessagingCenter class 实现了发布-订阅模式,允许组件之间基于消息的通信,这些通信不方便 link 通过对象和类型引用。这种机制允许发布者和订阅者在没有相互引用的情况下进行通信,有助于减少它们之间的依赖性。
发布消息
发布者通过 MessagingCenter.Send 重载之一通知订阅者消息。以下代码示例发布 Hi
消息:
MessagingCenter.Send<MainPage>(this, "Hi");
订阅消息
订阅者可以使用 MessagingCenter.Subscribe 重载之一注册接收消息。
MessagingCenter.Subscribe<MainPage> (this, "Hi", (sender) =>
{
// Do something whenever the "Hi" message is received
});
退订消息
订阅者可以取消订阅他们不想再接收的消息。这是通过 MessagingCenter.Unsubscribe 重载之一实现的:
MessagingCenter.Unsubscribe<MainPage>(this, "Hi");
更新:
And I don't understand how you can find out which element the user
clicked on
您可以为您的 DataTemplate
添加 TapGestureRecognizer。
我修改了你的 DataTemplate
并为其添加了 TapGestureRecognizer
。您可以参考以下代码:
<ContentPage.Resources>
<DataTemplate x:Key="ColorItemTemplate">
<Frame Margin="5"
HeightRequest="120"
BackgroundColor="Azure"
WidthRequest="105">
<Label Text="{Binding DayOfTraining}"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Frame.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.TypeListSelectedCommand, Source={x:Reference flexLayout}}" CommandParameter="{Binding}"></TapGestureRecognizer>
</Frame.GestureRecognizers>
</Frame>
</DataTemplate>
</ContentPage.Resources>
在classTrainingViewModel
中添加命令TypeListSelectedCommand
如下:
public ICommand TypeListSelectedCommand => new Command<PowerTraining>(selectedItem);
void selectedItem(PowerTraining obj)
{
PowerTraining item = obj as PowerTraining;
System.Diagnostics.Debug.WriteLine("clicked item = " + item.DayOfTraining);
}
注意:
1.flexLayout
是你的 FlexLayout
:
的 x:Name
<FlexLayout x:Name="flexLayout" />
此外,您可以像这样添加TapGestureRecognizer
:
<ContentPage.Resources>
<DataTemplate x:Key="ColorItemTemplate">
<Frame Margin="5"
HeightRequest="120"
BackgroundColor="Azure"
WidthRequest="105">
<Label Text="{Binding DayOfTraining}"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
</Frame.GestureRecognizers>
</Frame>
</DataTemplate>
</ContentPage.Resources>
并在CalendarOfTraining.xaml.cs
中添加函数TapGestureRecognizer_Tapped
:
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
Frame boxView = sender as Frame;
PowerTraining SelectedItem = (PowerTraining)boxView.BindingContext;
System.Diagnostics.Debug.WriteLine(" clicked item = " + SelectedItem.DayOfTraining);
}
我有 FlexLayout
用来显示 collection 的内容。我想实现当您单击 collection 的某个元素时执行命令的可能性。我想确保当您单击某个项目时,会加载另一个视图来加载与所选日期相对应的数据。如何让 collection 项对点击做出反应?
<ContentPage.Resources>
<DataTemplate x:Key="ColorItemTemplate">
<Grid Margin="5"
HeightRequest="120"
WidthRequest="105">
<BoxView Color="Azure" />
<Label Text="{Binding Day}"
HorizontalOptions="Center"
VerticalOptions="Center" />
</Grid>
</DataTemplate>
</ContentPage.Resources>
<StackLayout Margin="10">
<Label Text="CollectionView"
FontSize="30"
FontAttributes="Bold"
HorizontalOptions="Center" />
<Label Text="{Binding MyCollection.Count, StringFormat='Count: {0}'}" />
<ScrollView>
<FlexLayout Direction="Row"
Wrap="Wrap"
AlignItems="Center"
AlignContent="Center"
BindableLayout.ItemsSource="{Binding MyCollection}"
BindableLayout.ItemTemplate="{StaticResource ColorItemTemplate}"/>
</ScrollView>
</StackLayout>
but when clicking on an item, where do you want to send data to?
在上面的截图中,你可以在collection中看到20个objects。它们在 class 构造函数中创建,并显示它们的创建时间。
PowerTrainings = new ObservableCollection<PowerTraining>();
for (int i = 0; i < 20; i++)
{
PowerTrainings.Add(new PowerTraining() { DayOfTraining = dateTime });
}
根据我的想法,每次用户(特别是我,因为我自己做)从历史记录中选择特定的一天时,将加载另一个视图,该视图将显示他所做的练习在那一天。但是如何在 XAML 代码中正确实现一个代码,该代码将确定 collection 的这个特定元素被单击(其中显示日期)并将该日期传递给另一个视图,该视图基于属性 DayOfTraining
, 将在这一天用 classes 查询数据库并形成另一个 collection?
If I represent it by analogy with WPF, then I would create a MouseDoubleClick event and pass the object to another view through the SelectedIndex property. But in the case of Xamarin, I don't understand (yet) how everything works.
我可以将你的应用程序部署到我的模拟器,但是当点击一个项目时,你想将数据发送到哪里?
根据场景的不同,在两个视图之间传递数据有多种方式。
一个简单的方法是使用Xamarin.Forms MessagingCenter。
Xamarin.Forms MessagingCenter class 实现了发布-订阅模式,允许组件之间基于消息的通信,这些通信不方便 link 通过对象和类型引用。这种机制允许发布者和订阅者在没有相互引用的情况下进行通信,有助于减少它们之间的依赖性。
发布消息
发布者通过 MessagingCenter.Send 重载之一通知订阅者消息。以下代码示例发布 Hi
消息:
MessagingCenter.Send<MainPage>(this, "Hi");
订阅消息
订阅者可以使用 MessagingCenter.Subscribe 重载之一注册接收消息。
MessagingCenter.Subscribe<MainPage> (this, "Hi", (sender) =>
{
// Do something whenever the "Hi" message is received
});
退订消息
订阅者可以取消订阅他们不想再接收的消息。这是通过 MessagingCenter.Unsubscribe 重载之一实现的:
MessagingCenter.Unsubscribe<MainPage>(this, "Hi");
更新:
And I don't understand how you can find out which element the user clicked on
您可以为您的 DataTemplate
添加 TapGestureRecognizer。
我修改了你的 DataTemplate
并为其添加了 TapGestureRecognizer
。您可以参考以下代码:
<ContentPage.Resources>
<DataTemplate x:Key="ColorItemTemplate">
<Frame Margin="5"
HeightRequest="120"
BackgroundColor="Azure"
WidthRequest="105">
<Label Text="{Binding DayOfTraining}"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Frame.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.TypeListSelectedCommand, Source={x:Reference flexLayout}}" CommandParameter="{Binding}"></TapGestureRecognizer>
</Frame.GestureRecognizers>
</Frame>
</DataTemplate>
</ContentPage.Resources>
在classTrainingViewModel
中添加命令TypeListSelectedCommand
如下:
public ICommand TypeListSelectedCommand => new Command<PowerTraining>(selectedItem);
void selectedItem(PowerTraining obj)
{
PowerTraining item = obj as PowerTraining;
System.Diagnostics.Debug.WriteLine("clicked item = " + item.DayOfTraining);
}
注意:
1.flexLayout
是你的 FlexLayout
:
<FlexLayout x:Name="flexLayout" />
此外,您可以像这样添加TapGestureRecognizer
:
<ContentPage.Resources>
<DataTemplate x:Key="ColorItemTemplate">
<Frame Margin="5"
HeightRequest="120"
BackgroundColor="Azure"
WidthRequest="105">
<Label Text="{Binding DayOfTraining}"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
</Frame.GestureRecognizers>
</Frame>
</DataTemplate>
</ContentPage.Resources>
并在CalendarOfTraining.xaml.cs
中添加函数TapGestureRecognizer_Tapped
:
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
Frame boxView = sender as Frame;
PowerTraining SelectedItem = (PowerTraining)boxView.BindingContext;
System.Diagnostics.Debug.WriteLine(" clicked item = " + SelectedItem.DayOfTraining);
}