首页 > 解决方案 > 如何用不同的颜色绘制选择的项目?

问题描述

我有一个收藏

<CollectionView SelectionMode="Single" 
             ItemsSource="{Binding Cities}"
             ItemsLayout="HorizontalList">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout Margin="5">
                            <Image  Source="{Binding Image}" />
                            <Label TextColor="Black" text="Text"/>
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

当我选择一个项目时,如何使用不同颜色的图像和标签进行绘画?

标签: xamarin.forms

解决方案


根据您的描述,您在 CollectionView DataTemplate 中有 Image 和 Label,您想在选择一项时将 Image 和 Label 设置为不同的背景颜色,对吗?

如果是,我建议您可以使用绑定背景颜色来执行此操作,请查看我的代码:

  <ContentPage.Resources>
    <Style TargetType="StackLayout">
        <Setter Property="VisualStateManager.VisualStateGroups">
            <VisualStateGroupList>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Normal" />
                    <VisualState x:Name="Selected">
                        <VisualState.Setters>
                            <Setter Property="BackgroundColor" Value="White" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateGroupList>
        </Setter>

    </Style>
</ContentPage.Resources>
<ContentPage.Content>
    <StackLayout>
        <CollectionView
            ItemsSource="{Binding images}"
            SelectionChanged="CollectionView_SelectionChanged"
            SelectionMode="Single">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout Margin="5">
                        <Frame BackgroundColor="{Binding imagecolor}" CornerRadius="5">
                            <Image Source="{Binding Image}" />
                        </Frame>

                        <Label
                            BackgroundColor="{Binding labelcolor}"
                            Text="{Binding cityname}"
                            TextColor="Black" />
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>
</ContentPage.Content>

 public partial class Page3 : ContentPage
{
    public ObservableCollection<imagemodel> images { get; set; }
    public Page3()
    {
        InitializeComponent();

        images = new ObservableCollection<imagemodel>()
        {
            new imagemodel(){Image="a5.jpg",cityname="beijing",imagecolor=Color.White,labelcolor=Color.White},
            new imagemodel(){Image="a6.jpg",cityname="shanghai",imagecolor=Color.White,labelcolor=Color.White},
            new imagemodel(){Image="a7.jpg",cityname="shenzhen",imagecolor=Color.White,labelcolor=Color.White},
            new imagemodel(){Image="a8.jpg",cityname="xiamen",imagecolor=Color.White,labelcolor=Color.White}

        };
        this.BindingContext = this;
    }

    private void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        imagemodel previous = (e.PreviousSelection.FirstOrDefault() as imagemodel);
        imagemodel current = (e.CurrentSelection.FirstOrDefault() as imagemodel);

        //Set the current to the color you want
        current.imagecolor = Color.Pink;
        current.labelcolor = Color.Green;

        if (previous != null)
        {
            //Reset the previous to defaulr color
            previous.imagecolor = Color.White;
            previous.labelcolor = Color.White;
        }
    }
}

public class imagemodel:ViewModelBase
{
    public string Image { get; set; }
    public string cityname { get; set; }

    private Color _imagecolor;
    public Color imagecolor
    {
        get { return _imagecolor;  }
        set
        {
            _imagecolor = value;
            RaisePropertyChanged("imagecolor");
        }
    }

    private Color _labelcolor;
    public Color labelcolor
    {
        get { return _labelcolor; }

        set
        {
            _labelcolor = value;
            RaisePropertyChanged("labelcolor");
        }
    }
}

ViewModelbase 实现 INotifyPropertyChanged 接口:

 public class ViewModelBase : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;


    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

更新:

如果你想使用 mvvm 模式来做到这一点,并将 CollectionView_SelectionChanged 方法放在我的 viewModel 中,我建议你可以绑定SelectionChangedCommand来做到这一点,请看我的代码:

内容页面:

 <ContentPage.Resources>
    <Style TargetType="StackLayout">
        <Setter Property="VisualStateManager.VisualStateGroups">
            <VisualStateGroupList>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Normal" />
                    <VisualState x:Name="Selected">
                        <VisualState.Setters>
                            <Setter Property="BackgroundColor" Value="White" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateGroupList>
        </Setter>

    </Style>
</ContentPage.Resources>
<ContentPage.Content>
    <StackLayout>
        <CollectionView
            ItemsSource="{Binding images}"
            SelectedItem="{Binding CurrentSelection}"
            SelectionChangedCommand="{Binding selectioncommand}"
            SelectionMode="Single">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout Margin="5">
                        <Frame BackgroundColor="{Binding imagecolor}" CornerRadius="5">
                            <Image Source="{Binding Image}" />
                        </Frame>

                        <Label
                            BackgroundColor="{Binding labelcolor}"
                            Text="{Binding cityname}"
                            TextColor="Black" />
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>
</ContentPage.Content>

 public partial class Page3 : ContentPage
{

    public Page3()
    {
        InitializeComponent();

        this.BindingContext = new imageviewmodel();
    }        
}

imageviewmodel.cs:

public class imageviewmodel:ViewModelBase
{
    public ObservableCollection<imagemodel> images { get; set; }

    private imagemodel _PreviousSelection;

    public imagemodel PreviousSelection
    {
        get { return _PreviousSelection; }
        set
        {
            _PreviousSelection = value;
            RaisePropertyChanged("PreviousSelection");
        }
    }

    private imagemodel _CurrentSelection;

    public imagemodel CurrentSelection
    {
        get { return _CurrentSelection; }
        set
        {
            if(CurrentSelection!=value)
            {
                PreviousSelection = CurrentSelection;
                _CurrentSelection = value;
                RaisePropertyChanged("CurrentSelection");
            }

        }
    }

    public Command selectioncommand { get; set; }

    public imageviewmodel()
    {
        images = new ObservableCollection<imagemodel>()
        {
            new imagemodel(){Image="a5.jpg",cityname="beijing",imagecolor=Color.White,labelcolor=Color.White},
            new imagemodel(){Image="a6.jpg",cityname="shanghai",imagecolor=Color.White,labelcolor=Color.White},
            new imagemodel(){Image="a7.jpg",cityname="shenzhen",imagecolor=Color.White,labelcolor=Color.White},
            new imagemodel(){Image="a8.jpg",cityname="xiamen",imagecolor=Color.White,labelcolor=Color.White}

        };

        selectioncommand = new Command(changecolor);
    }

    private void changecolor()
    {
       foreach(imagemodel model in images)
        {
            if(model.cityname==CurrentSelection.cityname)
            {
                model.imagecolor = Color.Pink;
                model.labelcolor = Color.Green;


            }
            else if(PreviousSelection != null && model.cityname==PreviousSelection.cityname)
            {                 
                    model.imagecolor = Color.White;
                    model.labelcolor = Color.White;

            }
        }
    }
}

截图是一样的。

截图:

在此处输入图像描述


推荐阅读