【问题标题】:Button is not clickable in CollectionViewCollectionView 中的按钮不可点击
【发布时间】:2020-08-11 18:43:35
【问题描述】:

我有一个 CollectionView 和我的自定义按钮。我想用按钮制作一个网格。当我单击按钮时,它会更改背景颜色。我想在 void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e) 中写一些东西,并且标签的文本是 SELECTED 按钮的名称(类字段) .当我点击collectionview中的按钮时,它会改变颜色但按钮不可点击,它看不到它,如果我写图像它可以读取数据。请帮我使按钮可点击

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

}

【问题讨论】:

  • 您不能按名称引用模板中的元素。您需要修改元素绑定到的基础模型对象。如果您希望在单击按钮时发生操作,则需要使用 Clicked 处理程序,而不是 SelectionChanged。 SelectionChanged 将触发 Cell 中的任何点击事件,而不仅仅是按钮点击。
  • Button_OnClicked 的代码在哪里?单击按钮时会触发吗?
  • 您的问题是“按钮不可点击”,但在您的评论中它说“它有效”。我不明白您要解决的实际问题是什么。
  • @MariaKamenskyh 嗨,欢迎来到 SO!您能否分享一张图片来解释问题,这将清楚地了解您的需求。

标签: c# xamarin button xamarin.android collectionview


【解决方案1】:

虽然不是太了解问题,但是CollectionView中有关于Button点击事件的建议。我们将在绑定模型时使用Command and CommandParameter of Button。这就是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类来加载数据:

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&lt;Car&gt; 以仅存储一项以保持此集合视图是单选的。并在此处使用 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的文字。

【讨论】:

  • Junior Jiang - MSFT,太棒了!!!!非常感谢!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  • @MariaKamenskyh 很高兴能帮上忙!请不要忘记接受它作为答案(单击此答案左上角的✔),它将帮助有类似问题的其他人。 :-)
猜你喜欢
  • 2018-09-11
  • 2021-05-02
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
  • 2015-09-26
  • 1970-01-01
  • 1970-01-01
  • 2015-10-05
相关资源
最近更新 更多