How to change Gridview Item UI when Observable Collection change object state - xaml

I'm trying to only allow one toggle button inside my gridview toggle on. If the next one toggled, the previous toggle button must be de-toggle. the structure of my gridview are these:
GridView bind with an observable collection
Inside a gridview content a user-control represent the gridview item
<controls:AdaptiveGridView.ItemTemplate>
<DataTemplate x:DataType="data:FoodDTO">
<usercontrols:FoodCard FoodId="{x:Bind FoodId}" FoodName="{x:Bind FoodName}" FoodEnglishName="{x:Bind FoodEnglishName}" IsSelected="{Binding IsSelected, Mode=TwoWay}"
MainFoodIcon="{x:Bind MainIcon}" SecondaryFoodIcon="{x:Bind SecondaryIcon}" ToggleClick="FoodCard_ToggleClick"/>
</DataTemplate>
</controls:AdaptiveGridView.ItemTemplate>
Here is the XAML of my User-Control
<Grid Height="130" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="5" Padding="0">
<ToolkitControls:DropShadowPanel x:Name="DropShadowHolder" VerticalAlignment="Stretch" Margin="10" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
BlurRadius="20"
ShadowOpacity="0.5" OffsetX="1" OffsetY="20"
Color="Black">
<Grid Background="{ThemeResource SystemAltHighColor}" Height="100" CornerRadius="5" HorizontalAlignment="Stretch"
VerticalAlignment="Bottom" Padding="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ToggleButton Content="CHỌN" FontWeight="Bold" Click="ToggleButton_Click" IsChecked="{Binding IsSelected, Mode=TwoWay}"
VerticalAlignment="Bottom" Margin="10,0,0,10" Width="70" FontSize="12"/>
<Grid Grid.Column="1" VerticalAlignment="Bottom" Margin="11">
<StackPanel VerticalAlignment="Bottom">
<TextBlock Text="40%" />
<ProgressBar Height="30" CornerRadius="3" Value="40"/>
</StackPanel>
<PersonPicture Width="25" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,-10,0,0"/>
</Grid>
<TextBlock Text="{x:Bind FoodName, Mode=OneWay}" Grid.Column="1" Margin="6,0,0,0"
FontSize="15" />
</Grid>
</ToolkitControls:DropShadowPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left">
<Grid Margin="20,0,0,0">
<Image x:Name="MainFoodImage" Width="70" Height="70"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Image x:Name="SecondaryFoodImage" Width="20" Height="20"
VerticalAlignment="Top" HorizontalAlignment="Right"/>
</Grid>
<TextBlock Text="{x:Bind FoodEnglishName, Mode=OneWay}" VerticalAlignment="Top" Margin="6,-5,0,0"
FontSize="15" FontWeight="Bold" />
</StackPanel>
Here is the code behind of that UserControl
public sealed partial class FoodCard : UserControl, INotifyPropertyChanged
{
public int FoodId
{
get { return (int)GetValue(FoodIdProperty); }
set { SetValue(FoodIdProperty, value); }
}
// Using a DependencyProperty as the backing store for FoodId. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FoodIdProperty =
DependencyProperty.Register("FoodId", typeof(int), typeof(FoodCard), null);
public string FoodName
{
get { return (string)GetValue(FoodNameProperty); }
set { SetValue(FoodNameProperty, value); }
}
// Using a DependencyProperty as the backing store for FoodName. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FoodNameProperty =
DependencyProperty.Register("FoodName", typeof(string), typeof(FoodCard), null);
public string FoodEnglishName
{
get { return (string)GetValue(FoodEnglishNameProperty); }
set { SetValue(FoodEnglishNameProperty, value); }
}
// Using a DependencyProperty as the backing store for FoodEnglishName. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FoodEnglishNameProperty =
DependencyProperty.Register("FoodEnglishName", typeof(string), typeof(FoodCard), null);
public bool IsSelected
{
get { return (bool)GetValue(IsSelectedProperty); }
set {
SetValue(IsSelectedProperty, value);
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
}
}
}
// Using a DependencyProperty as the backing store for IsSelected. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsSelectedProperty =
DependencyProperty.Register("IsSelected", typeof(bool), typeof(FoodCard), new PropertyMetadata(null));
public int MainFoodIcon
{
get { return (int)GetValue(MainFoodIconProperty); }
set
{
SetValue(MainFoodIconProperty, value);
MainFoodImage.Source = new BitmapImage(new Uri(_mainFoods[value]));
}
}
// Using a DependencyProperty as the backing store for MainFoodIcon. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MainFoodIconProperty =
DependencyProperty.Register("MainFoodIcon", typeof(int), typeof(FoodCard), null);
public int? SecondaryFoodIcon
{
get { return (int?)GetValue(SecondaryFoodIconProperty); }
set
{
if(value != null)
{
SetValue(SecondaryFoodIconProperty, value);
SecondaryFoodImage.Source = new BitmapImage(new Uri(_secondaryFoods[value]));
}
else SecondaryFoodImage.Source = null;
}
}
// Using a DependencyProperty as the backing store for SecondaryFoodIcon. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SecondaryFoodIconProperty =
DependencyProperty.Register("SecondaryFoodIcon", typeof(int?), typeof(FoodCard), null);
private readonly IDictionary<int, string> _mainFoods = new Dictionary<int, string>
{
{ 1, "ms-appx:///Assets/FoodAssets/Rice.png"},
{ 2, "ms-appx:///Assets/FoodAssets/Bread.png"},
{ 3, "ms-appx:///Assets/FoodAssets/Spagheti.png"},
{ 4, "ms-appx:///Assets/FoodAssets/Noodle.png"},
{ 5, "ms-appx:///Assets/FoodAssets/LunchFood.png"}
};
private readonly IDictionary<int?, string> _secondaryFoods = new Dictionary<int?, string>
{
{ 6, "ms-appx:///Assets/FoodAssets/Meat.png"},
{ 7, "ms-appx:///Assets/FoodAssets/Chicken.png"},
{ 8, "ms-appx:///Assets/FoodAssets/Egg.png"},
{ 9, "ms-appx:///Assets/FoodAssets/Shrimp.png"},
{ 10, "ms-appx:///Assets/FoodAssets/Falafel.png"}
};
public event FoodCardEventHandler ToggleClick;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public FoodCard()
{
this.InitializeComponent();
}
private void ToggleButton_Click(object sender, RoutedEventArgs e)
{
ToggleClick?.Invoke(FoodId);
}
The dependency property that hook to the toggle button also enable OnNotifyPropertyChanged
in this code notice that I expose the ToggleButton_Click to let the Page that contain the gridview can handle the click. And here's how I handle it
private void FoodCard_ToggleClick(int foodId)
{
foreach(FoodDTO dto in Foods)
{
dto.IsSelected = false;
}
foreach (FoodDTO dto in Foods)
{
System.Diagnostics.Debug.WriteLine(dto.IsSelected);
System.Diagnostics.Debug.WriteLine("-------------");
}
}
I watch the console they are all output IsSelected is False, but the Toggle Button on the ui element doesn't de-toggle. Here is the FoodDTO
public class FoodDTO
{
public int FoodId { get; set; }
public string FoodName { get; set; }
public string FoodEnglishName { get; set; }
public int MainIcon { get; set; } = 5;
public int? SecondaryIcon { get; set; }
public decimal Percentage { get; set; }
public bool IsSelected { get; set; }
}

The reason the UI does not react to the change in IsSelected property is that the FoodDto is a POCO, and does not implement INotifyPropetyChanged. If you make sure to raise PropertyChanged when IsSelected changes, it will be reflected in the x:Bind in the DataTemplate and will also then flow into your UserControl.

Related

Xamarin Global Variable in XAML doesn't refresh until later (randomly)

I have 3 global variables in my app.xaml.cs.
public static bool _Code { get; set; }
public static bool _Full { get; set; }
public static bool _Common { get; set; }
I have code in a list that uses these variables to hide/show buttons.
<Grid>
<Label
Padding="4"
BackgroundColor="{DynamicResource ColorWindowBackground}"
HorizontalOptions="FillAndExpand"
IsVisible="{Binding Path=_Code, Source={x:DynamicResource Application.Current}}"
Text="{Binding CodeName}"
VerticalOptions="FillAndExpand" />
<Label
Padding="4"
BackgroundColor="{DynamicResource ColorWindowBackground}"
HorizontalOptions="FillAndExpand"
IsVisible="{Binding Path=_Full, Source={x:DynamicResource Application.Current}}"
Text="{Binding FullName}"
VerticalOptions="FillAndExpand" />
<Label
Padding="4"
BackgroundColor="{DynamicResource ColorWindowBackground}"
HorizontalOptions="FillAndExpand"
IsVisible="{Binding Path=_Common, Source={x:DynamicResource Application.Current}}"
Text="{Binding CommonName}"
VerticalOptions="FillAndExpand" />
</Grid>
I change these variables on another page.
private string selectedDisplayType;
public string SelectedDisplayType
{
get { return selectedDisplayType; }
set
{
if (value != selectedDisplayType)
{
SetProperty(ref selectedDisplayType, value);
if (selectedDisplayType != null)
{
//Update the Ui bools for showing the different types
if (SelectedDisplayType == DisplayType.Common.ToString())
{
SelectorEventObj.Common = true;
App._Code = false;
App._Common = true;
App._Full = false;
}
else if (SelectedDisplayType == DisplayType.Code.ToString())
{
SelectorEventObj.Code = true;
App._Code = true;
App._Common = false;
App._Full = false;
}
else
{
SelectorEventObj.Full = true;
App._Code = false;
App._Common = false;
App._Full = true;
}
}
}
}
However, when I go back to my page. The new button doesn't appear with the different values for the species.
If I click through the app a little, it appears after a random number of moves.
Is there something I need to do to let my model know that the Global Variable has changed?

Refresh xaml page every x seconds and keep the current expander state

I have a xamarin project. There is a scrollview with a list of expanders.
I like to refresh the page every x seconds, but keep the state of my expanders (isExpanded boolean).
How do I check the state of my expanders (or label, button, whatever) and keep these values during a refresh every x seconds?
I feel like I have to add a parameter to my behindcode function, similar to the 'object sender' during a tap or click event.
In the behindcode I am trying to refresh the page every x seconds with
Device.StartTimer(TimeSpan.FromSeconds(x),Updatefunction);
Currently they all have their default isExpanded (false) state when the page refreshes.
You can add a bool property in the viewModel, then binding this property to IsExpanded="{Binding Expand1Opened}" in <Expander> tab. When user click the Expander, IsExpanded will depend on the value of Expand1Opened property. no matter the refresh the page every x seconds, it will keep the current expander state. And I add Command for Expander, if Expander is clicked, value of Expand1Opened property will be changed in the ViewModel.
<RefreshView IsRefreshing="{Binding IsRefreshing}"
RefreshColor="Teal"
Command="{Binding RefreshCommand}">
<ScrollView>
<StackLayout>
<Expander IsExpanded="{Binding Expand1Opened}" Command="{Binding Expand1OpenedCommand}">
<Expander.Header>
<Label Text="List1"
FontAttributes="Bold"
FontSize="Medium" />
</Expander.Header>
<Grid Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<FlexLayout Direction="Row"
Wrap="Wrap"
AlignItems="Center"
AlignContent="Center"
BindableLayout.ItemsSource="{Binding Items}"
BindableLayout.ItemTemplate="{StaticResource ColorItemTemplate}" />
</Grid>
</Expander>
<Expander IsExpanded="{Binding Expand2Opened}" Command="{Binding Expand2OpenedCommand}">
<Expander.Header>
<Label Text="List2"
FontAttributes="Bold"
FontSize="Medium" />
</Expander.Header>
<Grid Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<FlexLayout Direction="Row"
Wrap="Wrap"
AlignItems="Center"
AlignContent="Center"
BindableLayout.ItemsSource="{Binding Items}"
BindableLayout.ItemTemplate="{StaticResource ColorItemTemplate}" />
</Grid>
</Expander>
</StackLayout>
</ScrollView>
</RefreshView>
Here is viewModel. I have two <Expander>, So I add two properties Expand1Opened and Expand2Opened, and add two Commands called Expand1OpenedCommand and Expand2OpenedCommand, if the <Expander> were clicked, Expand1OpenedCommand will be invoked, then value of Expand1Opened will be changed, If the refreshview was refreshed, value of Expand1Opened will not be changed, so expander's state wil be kept.
public class MainPageViewModel : INotifyPropertyChanged
{
const int RefreshDuration = 2;
int itemNumber = 1;
readonly Random random;
bool isRefreshing;
public bool IsRefreshing
{
get { return isRefreshing; }
set
{
isRefreshing = value;
OnPropertyChanged();
}
}
bool expand1Opened = false;
public bool Expand1Opened
{
get { return expand1Opened; }
set
{
expand1Opened = value;
OnPropertyChanged();
}
}
bool expand2Opened=false;
public bool Expand2Opened
{
get { return expand2Opened; }
set
{
expand2Opened = value;
OnPropertyChanged();
}
}
public ObservableCollection<Item> Items { get; private set; }
public ICommand RefreshCommand => new Command(async () => await RefreshItemsAsync());
public ICommand Expand1OpenedCommand { get; set; }
public ICommand Expand2OpenedCommand { get; set; }
public MainPageViewModel()
{
random = new Random();
Items = new ObservableCollection<Item>();
Expand1OpenedCommand = new Command((() =>
{
expand1Opened = !expand1Opened;
}));
Expand2OpenedCommand = new Command((() =>
{
expand2Opened = !expand2Opened;
}));
AddItems();
}
void AddItems()
{
for (int i = 0; i < 1; i++)
{
Items.Add(new Item
{
Color = Color.FromRgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)),
Name = $"Item {itemNumber++}",
Isfavourite = false
});
}
}
async Task RefreshItemsAsync()
{
IsRefreshing = true;
await Task.Delay(TimeSpan.FromSeconds(RefreshDuration));
AddItems();
IsRefreshing = false;
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
Here is running GIF.

Keep highlighting the cell when user deselect

I'm using Xamarin Forms ListView as a SideBar. How can I prevent users from deselecting cell? Or at least keep highlighting the cell when users deselect it.
This is how I'm binding
<ListView x:Name="listView" SelectionMode="Single">
<ListView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Management</x:String>
<x:String>Information</x:String>
<x:String>Language</x:String>
<x:String>Settings</x:String>
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
According to your description, when you select item from ListView, this item highlighting, you want to this item still highlighting when this item is not selected state. It seems that you want to select multiple item from ListView.
I've made a sample, you can take a look:
<ContentPage.Content>
<StackLayout>
<ListView
ItemTapped="ListView_ItemTapped"
ItemsSource="{Binding Items}"
SelectionMode="Single">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="{Binding background}" Orientation="Horizontal">
<Label
HorizontalOptions="StartAndExpand"
Text="{Binding DisplayName}"
TextColor="Fuchsia" />
<BoxView
HorizontalOptions="End"
IsVisible="{Binding Selected}"
Color="Fuchsia" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
public partial class Page10 : ContentPage
{
public Page10 ()
{
InitializeComponent ();
this.BindingContext = new MultiSelectItemsViewModel();
}
private void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
Model m = e.Item as Model;
if(m!=null)
{
m.Selected = !m.Selected;
if(m.background==Color.White)
{
m.background = Color.BlueViolet;
}
else
{
m.background = Color.White;
}
}
}
}
public class Model:ViewModelBase
{
public string DisplayName { get; set; }
private bool _Selected;
public bool Selected
{
get { return _Selected; }
set
{
_Selected = value;
RaisePropertyChanged("Selected");
}
}
private Color _background;
public Color background
{
get { return _background; }
set
{
_background = value;
RaisePropertyChanged("background");
}
}
}
public class MultiSelectItemsViewModel
{
public ObservableCollection<Model> Items { get; set; }
public MultiSelectItemsViewModel()
{
Items = new ObservableCollection<Model>();
Items.Add(new Model() { DisplayName = "AAA", Selected = false,background=Color.White });
Items.Add(new Model() { DisplayName = "BBB", Selected = false , background = Color.White });
Items.Add(new Model() { DisplayName = "CCC", Selected = false, background = Color.White });
Items.Add(new Model() { DisplayName = "DDD", Selected = false, background = Color.White });
Items.Add(new Model() { DisplayName = "EEE", Selected = false, background = Color.White });
}
}
Update:
Don't allow user to unselect the selected item.
private void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
Model m = e.Item as Model;
if(m!=null)
{
m.Selected = true;
m.background = Color.Blue;
}
}
Depending on your needs, I've done something similar but with controls inside each row, like a checkbox.
https://xamarinhelp.com/multiselect-listview-xamarin-forms/
Use the SelectedItem property of the ListView. As long as SelectedItem property is not set back to null, the currently selected item will remain highlighted.

Style Trigger only working one way when bound to IsEnabled of custom class

I made a custom TimePicker and am trying to have it disabled from the start, and only enable it whenever something was done first. To make it show as disabled I use a Style trigger to change it's appearence related to it's IsEnabled property.
My problem though is that this trigger only worked in first initialization so the style looks like its disabled. but once I Enable it the trigger doesnt change the appearence back. What am I missing?
my trigger
<Style TargetType="customControlls:BorderedTimePicker">
<Style.Triggers>
<Trigger TargetType="customControlls:BorderedTimePicker" Property="IsEnabled" Value="False">
<Setter Property="BorderColor" Value="{StaticResource varColBgGrey}" />
<Setter Property="TextColor" Value="{StaticResource varColBgGrey}" />
<Setter Property="Image" Value="ClockDisabled.png" />
</Trigger>
</Style.Triggers>
To more clarify, I am sure that IsEnabled got changed since the TimePicker works after setting enabled to true, but the appearence still doesn't change.
My custom TimePicker:
public class BorderedTimePicker : TimePicker
{
#region Bindables
public static readonly BindableProperty MinimumTimeProperty = BindableProperty.Create(nameof(MinimumTime), typeof(DateTime?), typeof(BorderedTimePicker), null);
public DateTime MinimumTime
{
get => (DateTime)GetValue(MinimumTimeProperty);
set => SetValue(MinimumTimeProperty, value);
}
public static readonly BindableProperty MaximumTimeProperty = BindableProperty.Create(nameof(MaximumTime), typeof(DateTime?), typeof(BorderedTimePicker), null);
public DateTime MaximumTime
{
get => (DateTime)GetValue(MaximumTimeProperty);
set => SetValue(MaximumTimeProperty, value);
}
public static readonly BindableProperty BorderColorProperty = BindableProperty.Create(nameof(BorderColor), typeof(Color), typeof(BorderedTimePicker), Color.DarkGray, BindingMode.TwoWay);
public Color BorderColor
{
get => (Color)GetValue(BorderColorProperty);
set
{
SetValue(BorderColorProperty, value);
OnPropertyChanged();
}
}
public static readonly BindableProperty TextSizeProperty = BindableProperty.Create(nameof(TextSize), typeof(int), typeof(BorderedTimePicker), 16);
public int TextSize
{
get => (int)GetValue(TextSizeProperty);
set => SetValue(TextSizeProperty, value);
}
public static readonly BindableProperty BorderThicknessProperty = BindableProperty.Create(nameof(BorderThickness), typeof(double), typeof(BorderedTimePicker), 2.0);
public double BorderThickness
{
get => (double)GetValue(BorderThicknessProperty);
set => SetValue(BorderThicknessProperty, value);
}
public static readonly BindableProperty BorderRadiusProperty = BindableProperty.Create(nameof(BorderRadius), typeof(double), typeof(BorderedTimePicker), 20.0);
public double BorderRadius
{
get => (double)GetValue(BorderRadiusProperty);
set => SetValue(BorderRadiusProperty, value);
}
public static readonly BindableProperty PlaceholderProperty = BindableProperty.Create(nameof(Placeholder), typeof(string), typeof(BorderedTimePicker), string.Empty);
public string Placeholder
{
get => (string)GetValue(PlaceholderProperty);
set => SetValue(PlaceholderProperty, value);
}
public static readonly BindableProperty ImageProperty = BindableProperty.Create(nameof(Image), typeof(string), typeof(BorderedTimePicker), string.Empty, BindingMode.TwoWay);
public string Image
{
get => (string)GetValue(ImageProperty);
set
{
SetValue(ImageProperty, value);
OnPropertyChanged();
}
}
public static readonly BindableProperty ImageSizeProperty = BindableProperty.Create(nameof(ImageSize), typeof(int), typeof(BorderedTimePicker), 35);
public int ImageSize
{
get => (int)GetValue(ImageSizeProperty);
set => SetValue(ImageSizeProperty, value);
}
public static readonly BindableProperty IsValidProperty = BindableProperty.Create(nameof(IsValid), typeof(bool), typeof(BorderedDatePicker), true);
public bool IsValid
{
get => (bool)GetValue(IsValidProperty);
set
{
SetValue(IsValidProperty, value);
OnPropertyChanged();
}
}
public static readonly BindableProperty NullableDateProperty = BindableProperty.Create(nameof(NullableDate), typeof(DateTime?), typeof(ExtendedDatePicker), null, BindingMode.TwoWay);
public DateTime? NullableDate
{
get => (DateTime?)GetValue(NullableDateProperty);
set
{
if (value != NullableDate)
{
SetValue(NullableDateProperty, value);
UpdateDate();
}
}
}
#endregion Bindables
public BorderedTimePicker()
{
}
private void UpdateDate()
{
if (NullableDate.HasValue)
{
Time = NullableDate.Value.TimeOfDay;
}
}
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == TimeProperty.PropertyName)
{
if (NullableDate != null) NullableDate = NullableDate.Value + Time;
}
}
EDIT: the relevant part of my viewCell where I use the trigger and the timepicker
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:customControlls="clr-namespace:CleanKISeCare.CustomControlls;assembly=CleanKISeCare"
xmlns:helpers="clr-namespace:Syncfusion.ListView.XForms.Helpers;assembly=Syncfusion.SfListView.XForms"
xmlns:converter="clr-namespace:CleanKISeCare.Converter;assembly=CleanKISeCare"
x:Class="CleanKISeCare.CustomControlls.DatePickerComponent"
x:Name="this">
<ViewCell.BindingContext>
<helpers:InverseBoolConverter x:Key="InverseBoolConverter" />
</ViewCell.BindingContext>
<StackLayout x:Name="mainView" BindingContext="{Binding .}" BackgroundColor="White" Padding="10">
<StackLayout.Resources>
<ResourceDictionary>
<helpers:InverseBoolConverter x:Key="InverseBoolConverter" />
<converter:StringDateTimeConverter x:Key="StringDateTimeConverter" />
<Style TargetType="customControlls:BorderedTimePicker">
<Style.Triggers>
<Trigger TargetType="customControlls:BorderedTimePicker" Property="IsEnabled" Value="False">
<Setter Property="BorderColor" Value="{StaticResource varColBgGrey}" />
<Setter Property="TextColor" Value="{StaticResource varColBgGrey}" />
<Setter Property="Image" Value="ClockDisabled.png" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</StackLayout.Resources>
<Grid Margin="10"
HorizontalOptions="CenterAndExpand">
<customControlls:BorderedTimePicker
Grid.Row="0" Grid.Column="1"
x:Name="timePicker"
Image="ClockPicker.png"
TextSize="14"
WidthRequest="160"
Placeholder="Zeit"
Margin="10,0,0,0"
HorizontalOptions="StartAndExpand"
MinimumTime="{Binding MinValue, Converter={StaticResource StringDateTimeConverter}}"
MaximumTime="{Binding MaxValue, Converter={StaticResource StringDateTimeConverter}}"
NullableDate="{Binding Answer, Source={x:Reference this}, Mode=TwoWay}"
BorderColor="{StaticResource varColLightDark}"
TextColor="{StaticResource varColDark}"
Format="HH:mm" />
</Grid>
</StackLayout>
</ViewCell>
and the code behind:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class DatePickerComponent : ViewCell
{
public DatePickerComponent()
{
InitializeComponent();
timePicker.IsEnabled = datePicker.NullableDate != null;
}
private static void OnPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
{
DatePickerComponent component = bindable as DatePickerComponent;
component?.SetDate(newvalue);
}
void SetDate(object newvalue)
{
timePicker.IsEnabled = newDate.Value.Date != defaultDate;
}
}

Listbox ItemTemplate events not working in WP8 MVVM?

I have a class named MizahPanoramaItems, a List named PanoramaKarikaturItems and a ViewModel named MizahViewModel. My problem is my listbox' datatemplate's events not working.
<Grid x:Name="LayoutRoot" Background="White">
<phone:Panorama SelectionChanged="panaromaMain_SelectionChanged"
x:Name="panaromaMain" Title="mizah"
Style="{StaticResource PanoramaStyle}"
Background="#FFECF0F1" Foreground="#FF040202">
<phone:Panorama.TitleTemplate>
<DataTemplate>
<!--<TextBlock Text="{Binding}" FontSize="100" Margin="0,20,0,0"></TextBlock>-->
</DataTemplate>
</phone:Panorama.TitleTemplate>
<phone:PanoramaItem x:Name="panoramaKarikatur" Header="karikatür" Orientation="Horizontal" Foreground="#A6CC33">
<ListBox Margin="0,0,0,10" ItemsSource="{Binding PanoramaKarikaturItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<MetroEventToCommand:EventToCommandManager.Collection>
<MetroEventToCommand:EventToCommand Command="{Binding PanoramaTypeSelection}" Event="Tap"/>
</MetroEventToCommand:EventToCommandManager.Collection>
<c4f:Tile Width="410" Height="200" Margin="0,12,0,0" Background="{Binding ElementName=panoramaKarikatur,Path=Foreground}" Label="{Binding Name}" Foreground="White">
<Grid>
<c4f:TileNotification Background="White" Content="{Binding Count}" Foreground="{Binding ElementName=panoramaKarikatur,Path=Foreground}"/>
<Image Source="{Binding ImagePath,Converter={StaticResource UriToImage}}" Stretch="None" Width="140" Height="150" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
</c4f:Tile>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</phone:PanoramaItem>.....
Here is my list in ViewModel;
private List<MizahPanoramaItems> panoramaKarikaturItems;
public List<MizahPanoramaItems> PanoramaKarikaturItems
{
get { return panoramaKarikaturItems; }
set { SetProperty<List<MizahPanoramaItems>>(ref panoramaKarikaturItems, value, "PanoramaKarikaturItems"); }
}
Here is my MizahPanoramaItems Class
public class MizahPanoramaItems:NotifyPropertyChanged
{
public MizahPanoramaItems()
{
PanoramaTypeSelection = new DelegateCommand(PanoramatypeSelectionAction);
}
public enum Types
{
Caps,
Karikatur,
DiziFilm
}
private int _count;
public int Count
{
get { return _count; }
set { SetProperty<int>(ref _count, value, "Count"); }
}
private Types _type;
public Types Type
{
get { return _type; }
set { SetProperty<Types>(ref _type, value, "Type"); }
}
private string _path;
public string Path
{
get { return _path; }
set { SetProperty<string>(ref _path, value, "Path"); }
}
private string _pathName;
public string PathName
{
get { return _pathName; }
set { SetProperty<string>(ref _pathName, value, "PathName"); }
}
private string _imagePath;
public string ImagePath
{
get { return _imagePath; }
set { SetProperty<string>(ref _imagePath, value, "ImagePath"); }
}
private string _name;
public string Name
{
get { return _name; }
set { SetProperty<string>(ref _name, value, "Name"); }
}
public ICommand PanoramaTypeSelection { get; set; }
public void PanoramatypeSelectionAction()
{
}
}
and my command implementation;
public ICommand PanoramaTypeSelection { get; set; }
public void PanoramatypeSelectionAction()
{
//it is not working
}
public MizahPanoramaItems()
{
PanoramaTypeSelection = new DelegateCommand(PanoramatypeSelectionAction);
}