Reputation: 530
I have implemented a slider menu as ListView and can easily assign the color to any icon in the menu. However, I am trying to change the color of the ListView row that was selected (specifically the icon). I have tried using converter, but the value never changes.
Here is my 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>
Here is the model:
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; }
}
And here is 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
}
}
I also have MainMenu where I control the navigation and have ListView_onSelected method, but even there I can't change the color of the icon.
Upvotes: 0
Views: 275
Reputation: 9234
Please achieve INotifyPropertyChanged
interface for MainMenuItem.cs
Then change the ForegroundColor attribute like following code.
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));
}
}
I do not what is achievement about controls:SuperListView
and controls:IconView
, I used listview
and ImageButton
to replace it, If item was selected. We can change the ImageButton
's background color for testing.
<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;
}
Here is running GIF.
Upvotes: 1