Skip to content

Instantly share code, notes, and snippets.

@dylanberry
Last active February 5, 2020 22:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dylanberry/644871a3b09f3dfe2a5aedc41c19e741 to your computer and use it in GitHub Desktop.
Save dylanberry/644871a3b09f3dfe2a5aedc41c19e741 to your computer and use it in GitHub Desktop.
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlFlags"
x:Class="XamlFlags.MainPage"
x:Name="Page">
<ContentPage.BindingContext>
<local:MainPageViewModel />
</ContentPage.BindingContext>
<StackLayout BindableLayout.ItemsSource="{Binding Options}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Frame CornerRadius="4" Padding="0">
<StackLayout Orientation="Horizontal" Padding="5"
BackgroundColor="White">
<StackLayout.Triggers>
<DataTrigger TargetType="StackLayout"
Binding="{Binding IsEnabled}"
Value="false">
<Setter Property="IsEnabled"
Value="false" />
</DataTrigger>
<MultiTrigger TargetType="StackLayout">
<MultiTrigger.Conditions>
<BindingCondition
Binding="{Binding IsEnabled}"
Value="false"/>
<BindingCondition
Binding="{Binding IsSelected}"
Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="BackgroundColor"
Value="DarkGray" />
</MultiTrigger>
<MultiTrigger TargetType="StackLayout">
<MultiTrigger.Conditions>
<BindingCondition
Binding="{Binding IsEnabled}"
Value="true"/>
<BindingCondition
Binding="{Binding IsSelected}"
Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="BackgroundColor"
Value="DarkBlue" />
</MultiTrigger>
</StackLayout.Triggers>
<Button Text="Select"
Command="{Binding BindingContext.SelectTypeCommand, Source={x:Reference Page}}"
CommandParameter="{Binding .}"/>
<Label Text="✓"
TextColor="White"
FontSize="12"
HorizontalOptions="EndAndExpand"
VerticalOptions="Center">
<Label.Triggers>
<DataTrigger TargetType="Label"
Binding="{Binding IsSelected}"
Value="False">
<Setter Property="IsVisible"
Value="False" />
</DataTrigger>
</Label.Triggers>
</Label>
<Label Text="{Binding Value}" TextColor="Black"
HorizontalOptions="EndAndExpand"
VerticalOptions="Center">
<Label.Triggers>
<MultiTrigger TargetType="Label">
<MultiTrigger.Conditions>
<BindingCondition
Binding="{Binding IsEnabled}"
Value="false"/>
<BindingCondition
Binding="{Binding IsSelected}"
Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="TextColor"
Value="LightGray" />
</MultiTrigger>
<MultiTrigger TargetType="Label">
<MultiTrigger.Conditions>
<BindingCondition
Binding="{Binding IsEnabled}"
Value="true"/>
<BindingCondition
Binding="{Binding IsSelected}"
Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="TextColor"
Value="White" />
</MultiTrigger>
</Label.Triggers>
</Label>
</StackLayout>
</Frame>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ContentPage>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Internals;
namespace XamlFlags
{
public class MainPageViewModel : BindableBase
{
public ICommand SelectTypeCommand { get; }
public List<OptionViewModel> Options { get; } = new List<OptionViewModel>
{
new OptionViewModel { Value = "Option 1-A", Category = "1", Variety = "A" },
new OptionViewModel { Value = "Option 1-B", Category = "1", Variety = "B" },
new OptionViewModel { Value = "Option 2-A", Category = "2", Variety = "A" },
new OptionViewModel { Value = "Option 2-B", Category = "2", Variety = "B" },
new OptionViewModel { Value = "Option 3-A", Category = "3", Variety = "A" },
new OptionViewModel { Value = "Option 3-B", Category = "3", Variety = "B" },
};
public MainPageViewModel()
{
SelectTypeCommand = new Command<OptionViewModel>(OnSelectType);
OnSelectType(Options.First());
}
private void OnSelectType(OptionViewModel option)
{
if (option is null) return;
// reset all options
Options.ForEach(o => { o.IsEnabled = false; o.IsSelected = false; });
// enable options of the same variety (ie. A,B)
Options.Where(o => o.Variety == option.Variety)
.ForEach(o => { o.IsEnabled = true; });
// enable options of the same category (ie. 1,2,3)
Options.Where(o => o.Category == option.Category)
.ForEach(o => { o.IsEnabled = true; });
// select the current option
option.IsSelected = true;
}
}
public class OptionViewModel : BindableBase
{
public string Value { get; set; }
public string Variety { get; set; }
public string Category { get; set; }
private bool _isEnabled;
public bool IsEnabled { get => _isEnabled; set => SetProperty(ref _isEnabled, value); }
private bool _isSelected;
public bool IsSelected { get => _isSelected; set => SetProperty(ref _isSelected, value); }
}
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string propertyName = null, Action onChanged = null, Action<T> onChanging = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
onChanging?.Invoke(value);
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment