Xamarin 列表视图选定项目更改图标颜色
Posted
技术标签:
【中文标题】Xamarin 列表视图选定项目更改图标颜色【英文标题】:Xamarin List View Selected Item Change Icon Color 【发布时间】:2021-02-05 10:49:45 【问题描述】:我已将滑块菜单实现为 ListView,并且可以轻松地将颜色分配给菜单中的任何图标。但是,我正在尝试更改所选 ListView 行的颜色(特别是图标)。我试过使用转换器,但值永远不会改变。
这是我的 xaml:
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="SycretBeauty.Screens.MainMenuMaster"
Title="Master"
xmlns:controls="clr-namespace:SycretBeauty;assembly=SycretBeauty"
xmlns:converters="clr-namespace:SycretBeauty.Converters;assembly=SycretBeauty"
BackgroundColor="StaticResource color_menu_item_background"
IconImageSource="images/menu.png">
<StackLayout
BackgroundColor="StaticResource color_header_banner_background">
<Image
VerticalOptions="Center"
HorizontalOptions="FillAndExpand"
Source="images/bannerVialang.png"
Margin="0,30,0,20">
</Image>
<controls:SuperListView
x:Name="MenuItemsListView"
SeparatorVisibility="Default"
HasUnevenRows="False"
Margin="0,0,0,0"
RowHeight="120"
IsScrollingEnable="False"
SelectedItem="Binding SelectedItem"
ItemsSource="Binding MenuItems"
BackgroundColor="StaticResource color_menu_item_background">
<d:ListView.ItemsSource>
<x:Array Type="x:Type x:String">
<x:String>Записаться</x:String>
<x:String>Акции</x:String>
<x:String>Уведомления</x:String>
<x:String>Личный кабинет</x:String>
<x:String>Контакты</x:String>
<x:String>Отзывы</x:String>
<x:String>Галерея</x:String>
<x:String>Поделиться</x:String>
</x:Array>
</d:ListView.ItemsSource>
<controls:SuperListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid
VerticalOptions="FillAndExpand"
ColumnSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackLayout
Grid.Column="0"
BackgroundColor="StaticResource color_menu_item_background"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<controls:IconView
VerticalOptions="CenterAndExpand"
HeightRequest="35"
Foreground="Binding ForegroundColor"
Source="Binding ImgSource">
</controls:IconView>
</StackLayout>
<Label
Grid.Column="0"
Text="Binding PushCount"
IsVisible="Binding PushUnread"
d:Text="23"
d:IsVisible="True"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
TextColor="White"/>
<StackLayout Grid.Column="1"
BackgroundColor="StaticResource color_menu_item_background"
VerticalOptions="CenterAndExpand"
HorizontalOptions="FillAndExpand">
</StackLayout>
<Label Grid.Column="2"
BackgroundColor="StaticResource color_menu_item_background"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center"
Text="Binding Title"
d:Text="Binding ."
Style="StaticResource font_menu_item_text"/>
</Grid>
</ViewCell>
</DataTemplate>
</controls:SuperListView.ItemTemplate>
</controls:SuperListView>
</StackLayout>
这是模型:
public class MainMenuItem
public MainMenuItem()
TargetType = typeof(MainMenuItem);
public int Id get; set;
public string ImgSource get; set;
public string Title get; set;
public Type TargetType get; set;
public Action ItemSelected get; set;
public string PushCount get; set;
public bool PushUnread get; set;
public Color ForegroundColor get; set;
这里是cs:
public partial class MainMenuMaster : ContentPage
public ListView ListView;
public AppContext Context get; set;
private float rowHeight;
public MainMenuMaster()
InitializeComponent();
BindingContext = new ViewModel();
ListView = MenuItemsListView;
ListView.SizeChanged += ListView_SizeChanged;
private void ListView_SizeChanged(object sender, EventArgs e)
var h = ListView.Height;
rowHeight = (float)(h / 8);
ListView.RowHeight = (int)rowHeight;
protected override void OnAppearing()
base.OnAppearing();
(BindingContext as ViewModel).UpdatePushCount(Context.UnreadPushCount);
public class ViewModel : INotifyPropertyChanged
public ObservableCollection<MainMenuItem> MenuItems get; set;
public AppContext Context get; set;
public ViewModel()
MenuItems = new ObservableCollection<MainMenuItem>(new[]
new MainMenuItem
Id = 0,
ImgSource = "images/signup.png",
Title = "Записаться",
TargetType = typeof(OnlineSignupScreen),
ItemSelected = () =>
Context.SelectSalonStart(typeof(OnlineSignupScreen));
,
ForegroundColor = Color.Gray
,
new MainMenuItem
Id = 1,
ImgSource = "images/promos",
Title = "Акции",
TargetType = typeof(PromosScreen),
ForegroundColor = Color.Gray,
,
new MainMenuItem
Id = 2,
ImgSource = "images/notify",
Title = "Уведомления",
TargetType = typeof(NotificationsScreen),
ForegroundColor = Color.Gray
,
new MainMenuItem
Id = 3,
ImgSource = "images/personal",
Title = "Личный кабинет",
TargetType = typeof(PersonalInfoScreen),
ForegroundColor = Color.Gray
,
new MainMenuItem
Id = 4,
ImgSource = "images/contacts",
Title = "Контакты",
TargetType = typeof(ContactsScreen),
ItemSelected = () =>
Context.SelectSalonStart(typeof(ContactsScreen));
,
ForegroundColor = Color.Gray
,
new MainMenuItem
Id = 5,
ImgSource = "images/feedback.png",
Title = "Отзывы",
TargetType = typeof(FeedbackScreen),
ItemSelected = () =>
Context.SelectSalonStart(typeof(FeedbackScreen));
,
ForegroundColor = Color.Gray
,
new MainMenuItem
Id = 6,
ImgSource = "images/gallery.png",
Title = "Галерея",
TargetType = typeof(GalleryScreen),
ItemSelected = () =>
Context.SelectSalonStart(typeof(GalleryScreen));
,
ForegroundColor = Color.Gray
,
new MainMenuItem
Id = 7,
ImgSource = "images/share",
Title = "Поделиться",
TargetType = typeof(ShareWithFriendScreen),
ForegroundColor = Color.Gray
);
public void UpdatePushCount(int count)
MenuItems[2].ImgSource = count > 0 ? "images/badge" : "images/notify";
MenuItems[2].PushCount = count.ToString();
MenuItems[2].PushUnread = count > 0;
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string propertyName = "")
if (PropertyChanged == null)
return;
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
#endregion
我还有控制导航的 MainMenu 和 ListView_onSelected 方法,但即使在那里我也无法更改图标的颜色。
【问题讨论】:
【参考方案1】:请为MainMenuItem.cs
实现INotifyPropertyChanged
接口
然后像下面的代码一样更改 ForegroundColor 属性。
public class MainMenuItem: INotifyPropertyChanged
public MainMenuItem()
TargetType = typeof(MainMenuItem);
public int Id get; set;
public string ImgSource get; set;
public string Title get; set;
public Type TargetType get; set;
public Action ItemSelected get; set;
public string PushCount get; set;
public bool PushUnread get; set;
private Color _foregroundColor;
public Color ForegroundColor
get return _foregroundColor;
set
_foregroundColor = value;
OnPropertyChanged("ForegroundColor");
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
我不知道controls:SuperListView
和controls:IconView
的成就是什么,我用listview
和ImageButton
替换它,如果项目被选中。我们可以更改ImageButton
的背景颜色进行测试。
<ImageButton
Source="Binding ImgSource"
VerticalOptions="CenterAndExpand"
HeightRequest="35"
BackgroundColor="Binding ForegroundColor"
>
</ImageButton>
private void MenuItemsListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
// MainMenuItem mainMenuItem = sender as MainMenuItem;
MainMenuItem mainMenuItem = viewModel.MenuItems[e.SelectedItemIndex];
mainMenuItem.ForegroundColor = Color.Red;
这里正在运行 GIF。
【讨论】:
我可以通过在列表视图的onSelected
方法中设置var item = e.selectedItem
和item.ForegroundColor = color
来设置项目的颜色。但是,当我在列表视图中选择其他元素时,颜色会停留在先前选择的行上。更改所选菜单项时如何“取消选择”其他元素?
您可以在模型中添加IsSelect
属性(请实现ForegroundColor
这样的格式)。执行MenuItemsListView_ItemSelected
方法时,可以判断IsSelect
的值,如果值为true,可以设置一种颜色,如果值为false,可以设置另一种颜色。
感谢它运行良好,但我注意到在 android 上,当我在页面之间切换时,主菜单中的选择器不会改变。有没有办法做到这一点?以上是关于Xamarin 列表视图选定项目更改图标颜色的主要内容,如果未能解决你的问题,请参考以下文章
设置列表视图项模板的背景颜色和列表背景颜色时,Xamarin Forms Listview 选定项背景颜色丢失
我可以以编程方式更改 Xamarin.Forms 中的 styles.xml 吗?