Xamarin Forms - SelectionChangedCommand未为CollectionView触发

koaltpgm  于 2023-10-14  发布在  其他
关注(0)|答案(7)|浏览(139)

下面的代码显示了一个CollectionView的简单示例。我没有收到SelectionChangedCommand的事件。有人能看出我做错了什么吗?
顺便说一句,完整的源代码可以在GitHub here上找到。

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:ControlDemo"
                 x:Class="ControlDemo.MainPage">

    <StackLayout>
        <CollectionView SelectionMode ="Single"
                        ItemsSource="{Binding Tags}"
                        SelectionChangedCommand="{Binding SelectedTagChanged}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout>
                        <Label Text="{Binding .}" />
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

</ContentPage>

MainPageModel.cs

public class MainPageModel : FreshBasePageModel
{
    public override void Init(object initData)
    {
        Tags = new List<string>() { "A", "B", "C" };
        base.Init(initData);
    }

    public List<string> Tags { get; set; }

    public Command SelectedTagChanged
    {
        get
        {
            return new Command(() =>
            {
            });
        }
    }
}
qq24tv8q

qq24tv8q1#

在我身边工作的几件事(除了SelectionMode = Single):

  • 确保你的命令的签名在你的PageModel上是<object>,并根据你的需要进行任何转换(特别是当你的集合变得更复杂的时候)。
  • 另外,在XAML中,您希望给予CollectionView一个名称并使用SelectedItem属性。SelectionChangedCommandParameter="{Binding SelectedItem, Source={x:Reference cvTagsCollectionView}}"
slhcrj9b

slhcrj9b2#

我使用你的代码并在我这边创建了一个演示,我添加了widthRequestHeightRequest来使collectionView工作:

<CollectionView            
              HeightRequest="170" 
              WidthRequest="200"                        
              SelectionMode="Single" 
              SelectionChangedCommand="{Binding SelectedTagChangedCommand}"
              ItemsSource="{Binding Tags}"      
         >

在我单击CollectionView中的不同项目后,SelectionChangedCommand确实被触发。
我在这里上传了一个示例,你可以检查它:collectionView-selectItemChanged-xamarin.forms

2guxujil

2guxujil3#

如果你想使用ViewModel,那么你应该使用SelectedItem的绑定:

<CollectionView ItemsSource="{Binding Monkeys}"
                SelectionMode="Single"
                SelectedItem="{Binding SelectedMonkey, Mode=TwoWay}">
    ...
</CollectionView>

在ViewModel中:

Monkey selectedMonkey;
    public Monkey SelectedMonkey
    {
        get
        {
            return selectedMonkey;
        }
        set
        {
            if (selectedMonkey != value)
            {
                selectedMonkey = value;
            }
        }
    }

所以每次你选择一个新的对象,SelectedMonkey就会被更新。
如果你想跟踪SelectionChanged,那么,它应该在代码隐藏中(不确定如何在视图模型中实现,文档中没有任何内容)

<CollectionView ItemsSource="{Binding Monkeys}"
                SelectionMode="Single"
                SelectionChanged="OnCollectionViewSelectionChanged">
    ...
</CollectionView>

在您的Page.xaml.cs中:

void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var previous = e.PreviousSelection;
    var current = e.CurrentSelection;
    ...
}
9o685dep

9o685dep4#

我改进了法布里西奥·P。这样回答:

  • 已将{RelativeSource Self}用于SelectionChangedCommandParameter。它有助于省略命名集合视图。

所以你的xaml部分应该是这样的:

<CollectionView
    ItemsSource="{Binding Objects}"
    SelectionMode="Single"
    SelectionChangedCommand="{Binding SelectObjectCommand}"
    SelectionChangedCommandParameter="{Binding SelectedItem, Source={RelativeSource Self}}">

在您的视图模型中:

public ICommand SelectObjectCommand => new Command<string>(i => { Debug.WriteLine("Selected: " + i); });
public IEnumerable<string> Objects { get; set; }
wljmcqd8

wljmcqd85#

看起来您没有设置SelectionMode属性。根据docs
默认情况下,CollectionView选择处于禁用状态。但是,可以通过将SelectionMode属性值设置为SelectionMode枚举成员之一来更改此行为:

  • 无-表示无法选择项目。这是默认值。
  • 单个-指示可以选择单个项目,并突出显示选定的项目。
  • 多个-指示可以选择多个项目,并突出显示选定的项目。

SelectionMode = Single添加到CollectionView将解决您的问题。

fhity93d

fhity93d6#

如果您正在使用模型,则可以使用以下方法
我的C#模型视图类

public class MainView : INotifyPropertyChanged
{
    public ICommand SelectionChangedCommands => new Command<GroupableItemsView>((GroupableItemsView query) =>
    { 
        GO_Account test = query.SelectedItem as GO_Account; 
    });

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    } 
    
}

这是我的XAML

<CollectionView  x:Name="myAccounts" 
    SelectionMode="Single" 
    ItemsSource="{Binding Products}" 
    SelectionChangedCommand="{Binding SelectionChangedCommands}"
    SelectionChangedCommandParameter="{Binding Source={x:Reference myAccountsModel}}">
</CollectionView>
tzcvj98z

tzcvj98z7#

我也有同样的问题,只有当我的命令被设置为对象时,SelectionChangedCommand才会触发,就像Fabricio P说的那样。
XAML

<CollectionView
  x:Name="ListaGiocatoriCollectionView"
  Grid.Row="3"
  Grid.ColumnSpan="2"
  Grid.RowSpan="4"
  SelectionMode="Multiple"
  ItemsSource="{Binding ListaGiocatori}"
  SelectionChangedCommand="{Binding PopolaListaGiocatoriScelti}"
  SelectionChangedCommandParameter="{Binding .,Source={x:Reference ListaGiocatoriCollectionView}}">

代码

public ICommand PopolaListaGiocatoriScelti => new Command<object>(async (user) =>
      {
            CollectionView cw = (CollectionView)user;
            IList<object> x = cw.SelectedItems;
            ListaGiocatoriScelti = new ObservableCollection<User>();
            foreach (object item in x)
            {
                ListaGiocatoriScelti.Add((User)item);
            }
        });

相关问题