单击 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);
    }