И TouchBehavior.CommandParameter, и TouchBehavior.LongPressCommandParameter всегда передаются как null в Command и LongPressCommand

И TouchBehavior.CommandParameter, и TouchBehavior.LongPressCommandParameter всегда передаются как null в Command и LongPressCommand.

В следующем примере при касании элемента в CollectionView результирующее предупреждение всегда будет отображаться Selected value:, поскольку CommandParameter всегда равен null. Например, когда пользователь нажимает Selected vale: Item 1, должно быть написано Item 1.

<VerticalStackLayout Padding = "30,0"
                     Spacing = "25">
    <Label Text = "{Binding Title}"
           Style = "{StaticResource Headline}"
           SemanticProperties.HeadingLevel = "Level1" />

    <Label Text = "Tapping or long pressing an item does not correctly pass that item as CommandParameter or LongTouchCommandParameter."
           Style = "{StaticResource SubHeadline}"
           SemanticProperties.HeadingLevel = "Level1"  />

    <CollectionView x:Name = "collectionView"
                    ItemsSource = "{Binding Items}">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType = "{x:Type x:String}">
                <Label Padding = "10"
                       Text = "{Binding .}"
                       x:Name = "Label">
                    <Label.Behaviors>
                        <toolkit:TouchBehavior Command = "{Binding Source = {x:Reference collectionView}, Path=BindingContext.ShowItemCommand}"
                                               CommandParameter = "{Binding .}"
                                               LongPressCommand = "{Binding Source = {x:Reference collectionView}, Path=BindingContext.ShowItemCommand}"
                                               LongPressCommandParameter = "{Binding .}"
                        <!--
                        CommandParameter and LongPressCommandParameter are always passed as null in the CommunityToolkit.Maui TouchBehavior.
                        this was not the case with https://github.com/Axemasta/Maui.TouchEffect -->
                    </Label.Behaviors>
                </Label>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

</VerticalStackLayout>
public partial class MainViewModel : ObservableObject
{
    public string Title => "Hello, Maui!";

    public ObservableCollection<string> Items { get; set; } = ["Item 1", "Item 2", "Item 3"];

    /// <summary>
    /// item is always null. This was not the case in https://github.com/Axemasta/Maui.TouchEffect
    /// </summary>
    /// <param name = "item"></param>
    /// <returns></returns>
    [RelayCommand]
    private Task ShowItem(string item) => Application.Current.MainPage.DisplayAlert($"Selected value:", item, "OK");
}

Образец воспроизведения

Вот ссылка на образец воспроизведения этой ошибки: https://github.com/hansmbakker/bugrepro-communitytoolkit-maui-touchbehavior-parameter

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
260
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Объяснение

В .NET MAUI вам необходимо вручную установить BindingContext для каждого Behavior. Другими словами, поведения не наследуют BindingContext от VisualElement, к которому они привязаны.

Источник: https://learn.microsoft.com/dotnet/maui/fundamentals/behaviors?view=net-maui-8.0#create-a-net-maui-behavior

Обновленный код

Вот обновленный XAML, который поможет вашему коду работать. Он использует привязку «представление-представление» для привязки TouchBehavior.BindingContext к Label.BindingContext:

<VerticalStackLayout Padding = "30,0"
                     Spacing = "25">
    <Label Text = "{Binding Title}"
           Style = "{StaticResource Headline}"
           SemanticProperties.HeadingLevel = "Level1" />

    <Label Text = "Tapping or long pressing an item does not correctly pass that item as CommandParameter or LongTouchCommandParameter."
           Style = "{StaticResource SubHeadline}"
           SemanticProperties.HeadingLevel = "Level1"  />

    <CollectionView x:Name = "collectionView"
                    ItemsSource = "{Binding Items}">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType = "{x:Type x:String}">
                <Label Padding = "10"
                       Text = "{Binding .}"
                       x:Name = "label">
                    <Label.Behaviors>
                        <toolkit:TouchBehavior Command = "{Binding Source = {x:Reference collectionView}, Path=BindingContext.ShowItemCommand}"
                                               CommandParameter = "{Binding .}"
                                               LongPressCommand = "{Binding Source = {x:Reference collectionView}, Path=BindingContext.ShowItemCommand}"
                                               LongPressCommandParameter = "{Binding .}"
                                               BindingContext = "{Binding Source = {x:Reference label}, Path=BindingContext}"/>
                    </Label.Behaviors>
                </Label>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

</VerticalStackLayout>

Немного не связанный с проблемой Behavior BindingContext, вот моя рекомендация по небольшому повышению производительности вашей ViewModel (оба Title и Items могут быть свойствами только для чтения):

public partial class MainViewModel : ObservableObject
{
    public string Title { get; } = "Hello, Maui!";

    public ObservableCollection<string> Items { get; } = ["Item 1", "Item 2", "Item 3"];

    [RelayCommand]
    private Task ShowItem(string item) => Application.Current.MainPage.DisplayAlert($"Selected value:", item, "OK");
}

Скриншот обновленного приложения

Вот снимок экрана вашего приложения, работающего должным образом после обновления кода:

Модульные тесты набора инструментов сообщества .NET MAUI

Вот модульные тесты, которые я написал для TouchBehavior в CommunityToolkit.Maui, где мы проверяем, что LongPressCommand действительно проходит в LongPressCommandParameter;

https://github.com/CommunityToolkit/Maui/blob/51dc63a7642370849e413d87072b668fa022e303/src/CommunityToolkit.Maui.UnitTests/Behaviors/TouchBehaviorTests.cs#L612-L674

А вот модульные тесты, которые я написал для TouchBehavior в CommunityToolkit.Maui, где мы проверяем, что Command действительно проходит в CommandParameter;

https://github.com/CommunityToolkit/Maui/blob/51dc63a7642370849e413d87072b668fa022e303/src/CommunityToolkit.Maui.UnitTests/Behaviors/TouchBehaviorTests.cs#L550-L610

Другие вопросы по теме