Maui EventToCommandBehavior 如何传递多个参数

问题描述 投票:0回答:1

我想要实现的目标

我有一个

EventToCommandBehavior
命令,它将事件参数作为参数传递给命令:“CheckedChanged”事件参数。我也需要它传递一个正常的旧参数。

这可能只是语法问题,我还没有找到正确的文档。我希望如此。

我当前的代码

非常简单的事情,真的。该命令发生在

Chcekbox
中的
CollectionView
控件中。基本上,我显示了一个“视频”类型(我自己的一类)类型的列表,每个列表旁边都有一个复选框。当用户单击复选框时,我会转到一个方法。我需要传递两个参数:

(1)

CheckChangedEventArg
,我通过了,并且
(2) 我们正在查看的对象“视频”,我不知道如何将其与
CheckChangedEventArg
一起传递。

这是 XAML:

<CollectionView ItemsSource="VideoList">
  ...
    <DataTemplate x:DataType="model:Video">
        ...
               <CheckBox>
                   <CheckBox.Behaviors>
                       <toolkit:EventToCommandBehavior
                            x:TypeArguments="CheckedChangedEventArgs"
                            EventName="CheckedChanged"
                            Command="{Binding Source={x:Reference this}, Path=BindingContext.AddRemoveFromListCommand}"/>
                  </CheckBox.Behaviors>
              </CheckBox>
       ...
   </DataTemplate>
  ...
</CollectionView>

这是视图模型:

[RelayCommand]
public void AddRemoveFromList(CheckedChangedEventArgs args)
{
    if (args.Value)
    {
          // do the thing
    }
    else
    {
          // do the other thing
    }
}

请注意,这是工作代码,只是它只通过了

CheckedChangedEVentArgs
。我需要它同时传递
CheckedChangedEventArgs
Video
(在
<DataTemplate/>
属性中提到)。

我尝试了什么?

我尝试阅读文档。答案可能就在那里,但我找不到。属性

xTypeArguments
的名称是复数,这让我想到也许我可以简单地添加另一个参数?

而且,唉,我可以访问该属性中的

Video
对象!

这让我觉得也许我需要做的就是这样:

<CheckBox.Behaviors>
    <toolkit:EventToCommandBehavior
            x:TypeArguments="CheckedChangedEventArgs, Video (model)"
            EventName="CheckedChanged"
            Command="{Binding Source={x:Reference this}, Path=BindingContext.AddRemoveFromListCommand}" 
            CommandParameter="{Binding VideoFilename}"
            />
</CheckBox.Behaviors>

并且:

    [RelayCommand]
    public void AddRemoveFromList(CheckedChangedEventArgs args, Video video)
    {
            ...
    }

但这行不通。

我也做了很多其他事情,涉及

CommandParameter
,但没有任何效果。

有人知道在这里做什么吗?

c# xaml parameters maui collectionview
1个回答
0
投票

你的代码不必那么复杂,你不需要同时通过

CheckedChangedEventArgs
Video (model)
。我们可以将视频Item(包括CheckBox的选中值)作为一个整体传递。

您只需向您的视频模型添加一个 bool 变量(例如

public bool IsChecked
)并为您的视频项实现
INotifyPropertyChanged
(例如
Item.cs
),然后将其绑定到此
IsChecked
的属性
CheckBox

一旦我们选中或取消选中

CheckBox
,该变量的值就会更新。所以,我们可以传递整个视频项。

我已经实现了这个功能,可以参考以下代码: 假设 Videl 模型为

Item.cs

Item.cs

public class Item: INotifyPropertyChanged
{
    public string SectionName { get; set; }


    //add a bool variable 
    private bool _isChecked;
    public bool IsChecked
    {
        set { SetProperty(ref _isChecked, value); }
        get { return _isChecked; }
    }

    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;
        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

MyViewModel.cs

在这里,我们可以通过代码获取整个传递的 Item

UpdateThisItemCommand = new Command<Item>(checkboxcommand);

public class MyViewModel: INotifyPropertyChanged
   {
       public ObservableCollection<Item> Sections { get; set; } = new ObservableCollection<Item>();

  
       public ICommand GetResultCommand { get; set; }
       public ICommand UpdateThisItemCommand { get; set; }


       public MyViewModel() {
           Sections.Add(new Item { SectionName= "section_1"});
           Sections.Add(new Item { SectionName= "section_2",IsChecked= true});
           Sections.Add(new Item { SectionName= "section_3" });


           GetResultCommand = new Command(getResult);

           UpdateThisItemCommand = new Command<Item>(checkboxcommand);

       }

       private void checkboxcommand(Item obj)
       {
           if (obj != null)
           {
               if (obj.IsChecked)
               {
                   // you also need to add some other logic codes here
                   System.Diagnostics.Debug.WriteLine($"{obj.SectionName}");
               }
               else {
                   System.Diagnostics.Debug.WriteLine($"{obj.SectionName}");

               }

           }
       }

       private void getResult()
       {
           foreach (var section in Sections)
           {
               if (section.IsChecked) {
                   System.Diagnostics.Debug.WriteLine(section.SectionName);
               }
           }
       }

       bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
       {
           if (Object.Equals(storage, value))
               return false;
           storage = value;
           OnPropertyChanged(propertyName);
           return true;
       }
       protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
       {
           PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
       }
       public event PropertyChangedEventHandler PropertyChanged;

   }

使用示例:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewdels="clr-namespace:MauiCheckListviewApp.ViewModes"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             x:Class="MauiCheckListviewApp.MainPage">

    <ContentPage.BindingContext>
        <viewdels:MyViewModel></viewdels:MyViewModel>
    </ContentPage.BindingContext>

    <VerticalStackLayout>
        <CollectionView ItemsSource="{Binding Sections}" x:Name="myCollectionView"
                                Grid.Row="1">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <HorizontalStackLayout>
                        <CheckBox Color="#0B4C90" IsChecked="{Binding IsChecked}">
                            <CheckBox.Behaviors>
                                <toolkit:EventToCommandBehavior
                                    Command="{Binding BindingContext.UpdateThisItemCommand, Source={x:Reference myCollectionView}}"
                                    CommandParameter="{Binding .}"
                                    EventName="CheckedChanged" />
                            </CheckBox.Behaviors>

                        </CheckBox>
                        <Label Text="{Binding SectionName}"
                                       FontSize="20"
                                       FontAttributes="Bold"
                                       TextColor="#0B4C90"/>
                    </HorizontalStackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

        <Button Text="Get Sections" Command="{Binding GetResultCommand}"/>
    </VerticalStackLayout>

</ContentPage>
© www.soinside.com 2019 - 2024. All rights reserved.