【问题标题】:Xamarin Forms - SelectionChangedCommand not firing for CollectionViewXamarin Forms - SelectionChangedCommand 不为 CollectionView 触发
【发布时间】:2019-11-08 11:42:48
【问题描述】:

下面的代码显示了一个 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(() =>
            {
            });
        }
    }
}

【问题讨论】:

    标签: xamarin xamarin.forms freshmvvm


    【解决方案1】:

    对我有用的几件事(除了SelectionMode = Single):

    • 确保您的 Command 签名在您的 PageModel 中为 &lt;object&gt;,并根据您的需要进行任何转换(特别是当您的集合变得更复杂时)。

    • 您还想在 XAML 中为 CollectionView 命名并使用 SelectedItem 属性。 SelectionChangedCommandParameter="{Binding SelectedItem, Source={x:Reference cvTagsCollectionView}}"

    【讨论】:

      【解决方案2】:

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

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

      SelectionChangedCommand 在我单击 CollectionView 中的不同项目后触发。

      我在这里上传了一个示例,你可以查看:collectionView-selectItemChanged-xamarin.forms

      【讨论】:

        【解决方案3】:

        您似乎没有设置 SelectionMode 属性。根据docs

        默认情况下,CollectionView 选择被禁用。但是,可以通过将 SelectionMode 属性值设置为 SelectionMode 枚举成员之一来更改此行为:

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

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

        【讨论】:

        • 好收获。我添加了 SelectionMode=Single,但我仍然没有收到该事件。我用新代码和 repo 更新了我的问题。我还缺少其他什么吗?
        【解决方案4】:

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

        <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;
            ...
        }
        

        【讨论】:

        • 谢谢。但是,我正在使用 FreshMVVM 库来处理您上面的所有管道代码。这是一个示例项目,但在我的主代码库中,所有绑定(包括 ICommands)都运行良好。我已经从 XF 演示 repo 下载了 CollectionView 示例,并且正在查看是否也存在问题。
        【解决方案5】:

        如果您正在使用模型,您可以使用以下方法

        我的 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>
        

        【讨论】:

          【解决方案6】:

          我以这种方式改进了 Fabricio 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; }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-02-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-16
            • 2020-10-18
            • 1970-01-01
            相关资源
            最近更新 更多