To allow user to select only one checkbox at a time in LongListselector or ListBox of windows phone follow the below given steps. To achieve this the key points are implementing INotifyPropertyChanged Interface and setting Binding Mode Mode=TwoWay, so that whenever change occurs either in data or in UI, both get reflected.
Credits: Scott Logic
Step 1:
First create the UI for our LongListSelector.
- <phone:PhoneApplicationPage
- x:Class="LongListSelector_With_Check_Boxes.MainPage"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="Portrait" Orientation="Portrait"
- shell:SystemTray.IsVisible="False">
- <phone:PhoneApplicationPage.Resources>
- <Style x:Key="CheckBoxStyle" TargetType="CheckBox">
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="CheckBox">
- <Grid Background="Transparent" HorizontalAlignment="Left">
- <!--Margin input-->
- <VisualStateManager.VisualStateGroups>
- <VisualStateGroup x:Name="CommonStates">
- <VisualState x:Name="Normal"/>
- <VisualState x:Name="MouseOver"/>
- <VisualState x:Name="Disabled">
- <Storyboard>
- <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="CheckBackground">
- <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
- </ObjectAnimationUsingKeyFrames>
- <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="CheckMark">
- <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
- </ObjectAnimationUsingKeyFrames>
- <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="IndeterminateMark">
- <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
- </ObjectAnimationUsingKeyFrames>
- <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
- <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
- </ObjectAnimationUsingKeyFrames>
- </Storyboard>
- </VisualState>
- </VisualStateGroup>
- <VisualStateGroup x:Name="CheckStates">
- <VisualState x:Name="Checked">
- <Storyboard>
- <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="CheckMark">
- <DiscreteObjectKeyFrame KeyTime="0">
- <DiscreteObjectKeyFrame.Value>
- <Visibility>Visible</Visibility>
- </DiscreteObjectKeyFrame.Value>
- </DiscreteObjectKeyFrame>
- </ObjectAnimationUsingKeyFrames>
- </Storyboard>
- </VisualState>
- <VisualState x:Name="Unchecked"/>
- <VisualState x:Name="Indeterminate">
- <Storyboard>
- <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="IndeterminateMark">
- <DiscreteObjectKeyFrame KeyTime="0">
- <DiscreteObjectKeyFrame.Value>
- <Visibility>Visible</Visibility>
- </DiscreteObjectKeyFrame.Value>
- </DiscreteObjectKeyFrame>
- </ObjectAnimationUsingKeyFrames>
- </Storyboard>
- </VisualState>
- </VisualStateGroup>
- </VisualStateManager.VisualStateGroups>
- <Grid Margin="{StaticResource PhoneTouchTargetLargeOverhang}">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="32"/>
- <ColumnDefinition Width="*"/>
- </Grid.ColumnDefinitions>
- <Grid Grid.Column="0" VerticalAlignment="Top">
- <Border x:Name="CheckBackground" BorderBrush="#9db0b5" BorderThickness="{StaticResource PhoneBorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="Left" Height="32" IsHitTestVisible="False" VerticalAlignment="Center" Width="32"/>
- <Rectangle x:Name="IndeterminateMark" Fill="{StaticResource PhoneRadioCheckBoxCheckBrush}" HorizontalAlignment="Center" Height="16" IsHitTestVisible="False" Visibility="Collapsed" VerticalAlignment="Center" Width="16"/>
- <Path x:Name="CheckMark" Data="M0,123 L39,93 L124,164 L256,18 L295,49 L124,240 z" Fill="#9db0b5" FlowDirection="LeftToRight" HorizontalAlignment="Center" Height="21" IsHitTestVisible="False" Stretch="Fill" StrokeThickness="3" StrokeLineJoin="Round" Visibility="Collapsed" VerticalAlignment="Center" Width="23"/>
- </Grid>
- </Grid>
- </Grid>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- <DataTemplate x:Key="groupHeaderTemplate">
- <StackPanel Grid.Row="0" Background="White">
- <TextBlock Text="{Binding Title}" Foreground="Red"></TextBlock>
- </StackPanel>
- </DataTemplate>
- <phone:JumpListItemBackgroundConverter x:Key="BackgroundConverter"/>
- <phone:JumpListItemForegroundConverter x:Key="ForegroundConverter"/>
- <Style x:Key="LLSJumpListStyle" TargetType="phone:LongListSelector">
- <Setter Property="GridCellSize" Value="113,113"/>
- <Setter Property="LayoutMode" Value="Grid" />
- <Setter Property="ItemTemplate">
- <Setter.Value>
- <DataTemplate>
- <Border Background="{Binding Converter={StaticResource BackgroundConverter}}" Width="113" Height="113" Margin="6" >
- <TextBlock Text="{Binding Key}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" FontSize="48" Padding="6"
- Foreground="{Binding Converter={StaticResource ForegroundConverter}}" VerticalAlignment="Center"/>
- </Border>
- </DataTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- <Style x:Name="DividerStyle" TargetType="Border">
- <Setter Property="BorderBrush" Value="Gray"></Setter>
- <Setter Property="BorderThickness" Value="0 0 0 1"></Setter>
- <Setter Property="Margin" Value="0 18 0 18"></Setter>
- <Setter Property="Width" Value="450"></Setter>
- <Setter Property="Opacity" Value="0.7"></Setter>
- </Style>
- </phone:PhoneApplicationPage.Resources>
- <!--LayoutRoot is the root grid where all page content is placed-->
- <Grid x:Name="LayoutRoot" Background="Transparent">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
- <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
- <TextBlock Text="Demo App" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
- </StackPanel>
- <!--ContentPanel - place additional content here-->
- <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
- <phone:LongListSelector x:Name="lbTags" Background="Transparent"
- Margin="10,0"
- LayoutMode="List"
- SelectionChanged="llsPref_SelectionChanged">
- <phone:LongListSelector.ItemTemplate>
- <DataTemplate>
- <Grid HorizontalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="*"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="0.5*"/>
- <ColumnDefinition Width="3*"/>
- </Grid.ColumnDefinitions>
- <CheckBox Grid.Column="0" IsChecked="{Binding CheckboxState, Mode=TwoWay}" Grid.Row="0" Grid.RowSpan="2" x:Name="chkDelete" Visibility="Visible" Margin="2,16,10,20" Grid.ColumnSpan="2" Click="CheckBox_Click" />
- <TextBlock Text="{Binding NoteName}" FontSize="{StaticResource PhoneFontSizeLarge}" FontFamily="Segoe WP" Grid.Row="0" Foreground="Red" Grid.Column="1" Margin="12,24,0,0" />
- </Grid>
- </DataTemplate>
- </phone:LongListSelector.ItemTemplate>
- </phone:LongListSelector>
- </Grid>
- </Grid>
- </phone:PhoneApplicationPage>
Now Implement the Class File
- public class sample_data: INotifyPropertyChanged
- {
-
- public sample_data(string noteName, Boolean checkboxState)
- {
- this.NoteName = noteName;
- this.CheckboxState = checkboxState;
- }
-
-
-
- public event PropertyChangedEventHandler PropertyChanged;
- private void NotifyPropertyChanged(String propertyName)
- {
- PropertyChangedEventHandler handler = PropertyChanged;
- if (null != handler)
- {
- handler(this, new PropertyChangedEventArgs(propertyName));
- }
- }
-
-
-
- Boolean checkbox_state;
- public Boolean CheckboxState
- {
- get
- {
- return checkbox_state;
- }
- set
- {
- checkbox_state = value;
- NotifyPropertyChanged("CheckboxState");
- }
- }
-
-
- string note_name;
- public string NoteName
- {
- get {
- return note_name;
- }
- set {
- note_name = value;
- NotifyPropertyChanged("NoteName");
- }
- }
-
-
- }
NotifyPropertyChanged notifies that something is changed, Observable Collection always watches the collection for any changes.
Now go to MainPage.xaml.cs Page
- public partial class MainPage: PhoneApplicationPage
- {
-
- List < sample_data > currentList = new List < sample_data > ();
-
-
- public MainPage()
- {
- InitializeComponent();
- lbTags.ItemsSource = CreateData();
- }
- public ObservableCollection < sample_data > CreateData()
- {
- ObservableCollection < sample_data > my_list = new ObservableCollection < sample_data > ();
- my_list.Add(new sample_data("one", false));
- my_list.Add(new sample_data("two", true));
- my_list.Add(new sample_data("three", false));
- my_list.Add(new sample_data("four", true));
- my_list.Add(new sample_data("five", false));
- my_list.Add(new sample_data("six", true));
- my_list.Add(new sample_data("seven", false));
- my_list.Add(new sample_data("eight", true));
- return my_list;
- }
- public void CheckBox_Click(object sender, RoutedEventArgs e)
- {
- CheckBox chk = (CheckBox) sender;
- var checkBox = (CheckBox) sender;
- var data = (sample_data) chk.DataContext;
- var id = data.NoteName;
- foreach(sample_data sd in lbTags.ItemsSource)
- {
- if (id == sd.NoteName)
- {
- sd.CheckboxState = data.CheckboxState;
-
- }
- else
- {
- sd.CheckboxState = data.CheckboxState ? false : false;
-
- }
- }
-
-
- }
- public void llsPref_SelectionChanged(object sender, SelectionChangedEventArgs e) {}
- }
If you have any doubt please comment below and find the attached demo project for any reference.
Thank You!