按钮在 CollectionView 中不可点击

Button is not clickable in CollectionView

我有一个 CollectionView 和我的自定义按钮。我想用 buttons.When 创建一个网格 我点击按钮它改变了背景 color.I 想在 void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e) 中写一些东西并且标签的文本是 Name(class 字段) 的选择 button.When 我点击 collectionview 中的按钮它改变颜色但按钮不可点击,它看不到它,如果我写图像它可以读取 data.Please 帮助我使按钮可点击

<StackLayout>
                <Label  x:Name="meow1"></Label>
                <CollectionView  ItemsSource="{Binding Cars}" x:Name="phonesList" 
                         HeightRequest="90"
                         ItemsLayout="HorizontalList"
                        
                         BackgroundColor="Transparent"
                         SelectionMode="Single"
                         SelectionChanged="OnCollectionViewSelectionChanged">

                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                        <Frame x:Name="frame" CornerRadius="10"  BackgroundColor="Black" Padding="0"    HeightRequest="90"
                       WidthRequest="95">
                                <Grid Padding="0" x:Name="meow">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition Height="Auto" />
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto" />
                                        <ColumnDefinition Width="Auto" />
                                    </Grid.ColumnDefinitions>
                                <controls:CustomButton TintColor="#725762" HeightRequest="90"
                                                         WidthRequest="90" CornerRadius="10" HorizontalOptions="Center" 
                                                         BackgroundColor="White" ImageSource="{Binding ImagePath}" Clicked="Button_OnClicked"/>
                            </Grid>
                            </Frame>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>

            </StackLayout>

     void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
            {
               meow1.Text = (e.CurrentSelection.FirstOrDefault() as Car).NameImage;
        

}

虽然不是太了解问题,但是CollectionView中有关于Button点击事件的建议。我们将使用 Command and CommandParameter of Button when binding model . And that is the design idea of MVVM.

例如Xaml代码修改如下:

<StackLayout>
    <Label x:Name="meow1" 
           Text="{Binding SelectedCarItem.NameImage}"
           FontSize="Large"
           VerticalOptions="Start" 
           HorizontalOptions="CenterAndExpand" />
    <CollectionView  ItemsSource="{Binding Cars}"
                        x:Name="phonesList"
                        HeightRequest="90"
                        ItemsLayout="HorizontalList"
                        BackgroundColor="Transparent"
                        SelectionMode="Single"
                        SelectedItem="{Binding SelectedCarItem}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Frame x:Name="frame"
                        CornerRadius="10"
                        BackgroundColor="{Binding BgFrameColor}"
                        Padding="0"
                        HeightRequest="90"
                        WidthRequest="95">
                    <Grid Padding="0"
                            x:Name="meow">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Button 
                            HeightRequest="90"
                            WidthRequest="90"
                            CornerRadius="10"
                            HorizontalOptions="Center"
                            BackgroundColor="{Binding BgButtonColor}"
                            ImageSource="{Binding ImagePath}"
                            Command="{Binding TapCommand}"
                            CommandParameter="{Binding Source={x:Reference frame}, Path=BindingContext}" />
                    </Grid>
                </Frame>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</StackLayout>

然后需要修改Car模型,添加BgColor,IsSelectedTapCommand 属性:

public class Car : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    public string NameImage { get; set; } 
    public string ImagePath { get; set; }

    private Color bgFrameColor;

    public Color BgFrameColor
    {
        set
        {
            if (bgFrameColor != value)
            {
                bgFrameColor = value;
                OnPropertyChanged("BgFrameColor");
            }
        }
        get
        {
            return bgFrameColor;
        }
    }

    private Color bgButtonColor;

    public Color BgButtonColor
    {
        set
        {
            if (bgButtonColor != value)
            {
                bgButtonColor = value;
                OnPropertyChanged("BgButtonColor");
            }
        }
        get
        {
            return bgButtonColor;
        }
    }

    private bool isSelected;

    public bool IsSelected
    {
        set
        {
            if (isSelected != value)
            {
                isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }
        get
        {
            return isSelected;
        }
    }

    public ICommand TapCommand
    {
        get
        {
            return new Command((e) =>
            {
                var item = (e as Car);
                // logic on item
                if (item.isSelected)
                {
                    item.isSelected = false;
                    item.BgButtonColor = Color.White;
                    item.BgFrameColor = Color.Black;
                    PageCollectionView.SelectedCar.Remove(item);
                    MessagingCenter.Send<object, Car>(this, "Hi", new Car() {NameImage ="Welcome to the car home!" });
                }
                else
                {
                    item.isSelected = true;
                    item.BgButtonColor = Color.Blue;
                    item.BgFrameColor = Color.Yellow;
                    if (PageCollectionView.SelectedCar.Count == 0)
                    {
                        PageCollectionView.SelectedCar.Add(item);
                    }
                    else
                    {
                        PageCollectionView.SelectedCar[0].isSelected = false;
                        PageCollectionView.SelectedCar[0].BgButtonColor = Color.White;
                        PageCollectionView.SelectedCar[0].BgFrameColor = Color.Black;
                        PageCollectionView.SelectedCar.Remove(PageCollectionView.SelectedCar[0]);
                        PageCollectionView.SelectedCar.Add(item);
                    }
                    MessagingCenter.Send<object, Car>(this, "Hi", item);
                }

            });
        }
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

添加CarModel class加载数据:

public class CarModel: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public List<Car> Cars { get; set; }

    //public static Car SelectedCarItem { set; get; }
    public CarModel()
    {
        Cars = new List<Car>();
        Cars.Add(new Car() { NameImage = "Lexus", ImagePath = "Lexus.png", BgButtonColor = Color.White, BgFrameColor = Color.Black, IsSelected = false }); ;
        Cars.Add(new Car { NameImage = "Audi", ImagePath = "Audi.png", BgButtonColor = Color.White, BgFrameColor = Color.Black, IsSelected = false });
        // set default text of label 
        selectedCarItem = new Car() { NameImage = "Welcome to the car home!" };
    }

    private Car selectedCarItem;
    public Car SelectedCarItem
    {
        get
        {
            return selectedCarItem;
        }
        set
        {
            if (selectedCarItem != value)
            {
                selectedCarItem = value;
                OnPropertyChanged("SelectedCarItem");
            }
        }
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

现在在 ContentPage 中,声明一个 List<Car> 以仅存储一个项目以保持此集合视图是单选的。并在此处使用 MessagingCenter 更新 carModel.SelectedCarItem

public partial class PageCollectionView : ContentPage
{
    public static List<Car> SelectedCar { get; set; }

    public PageCollectionView()
    {
        InitializeComponent();

        CarModel carModel = new CarModel();
        BindingContext = carModel;

        SelectedCar = new List<Car>();

        MessagingCenter.Subscribe<object,Car>(this, "Hi", (sender,arg) =>
        {
            // Do something whenever the "Hi" message is received
            carModel.SelectedCarItem = arg;
        });

    }

}

效果如下:

注意:从示例中,您将看到使用绑定修改 BackgroundColor 和模型数据。因此,不建议使用OnCollectionViewSelectionChanged修改Lable的文本。