Search code examples
c#mvvmbindingbooleanwindows-rt

How to dynamically set ComboBox binding based on bool values?


I've come across the situation where I need to dynamically set the combo box's Items source, based on which toggle button is selected.

In the app there are two toggle buttons, Higher/Ordinary. I want to set the combo box's binding to the list higherGradePointKV if Higher is toggled, else if Ordinary is toggled to ordinaryGradePointKV.

So far, I set up to Bool properties, for Higher/Ordinary and a SetGradeComboBoxBinding() which is called in the View Model's constructor.

The part I'm struggling with is setting the binding from the code behind in this method.

Does anyone know how I can set the rest of this implementation up?

This is the ViewModel where the bool properties and lists are defined and called:

namespace LC_Points.ViewModel
{

    public class MainViewModel : ViewModelBase
    {

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            //call methods to initilise list data
            SetGradeComboBoxBinding();
            GetOrdinaryGradePairs();
            GetHigherGradePairs();
        }

        public List<StringKeyValue> higherGradePointKV { get; set; }
        public List<StringKeyValue> ordinaryGradePointKV { get; set; }


        //ordinary toggle button bool
        private bool _isOrdinaryToggled;
        public bool IsOrdinaryToggled
        {
            get
            {
                return _isOrdinaryToggled;
            }
            set
            {
                _isOrdinaryToggled = value;
                RaisePropertyChanged("IsOrdinaryToggled");
            }
        }

        //Higher toggle button bool property
        private bool _isHigherToggled;
        public bool IsHigherToggled
        {
            get
            {
                return _isHigherToggled;
            }
            set
            {
                _isHigherToggled = value;
                RaisePropertyChanged("IsHigherToggled");
            }
        }


        //Sets the grade combo box binding based on button toggled.
        public void SetGradeComboBoxBinding()
        {

            if(_isHigherToggled)
            {
                //set binding to higherGradePointKV

            }
            else if(_isOrdinaryToggled)
            {

                //set binding to higherGradePointKV


            }

        }


        public class StringKeyValue
        {
            public string Key { get; set; }
            public int Value { get; set; }
        }


        public void GetOrdinaryGradePairs()
        {

            List<StringKeyValue> ordianryGradePointKVTemp = new List<StringKeyValue>();


            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "A1", Value = 60 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "A2", Value = 50 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "B1", Value = 45 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "B2", Value = 40 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "B3", Value = 35 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "C1", Value = 30 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "C2", Value = 25 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "C3", Value = 20 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "D1", Value = 15 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "D2", Value = 10 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "D3", Value = 5 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "E,F,NG", Value = 0 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "Pass", Value = 30 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "Merit", Value = 50 });
            ordianryGradePointKVTemp.Add(new StringKeyValue { Key = "Distinction", Value = 70 });


            ordinaryGradePointKV = ordianryGradePointKVTemp;

        }


        public void GetHigherGradePairs()
        {

            List<StringKeyValue> higherGradePointKVTemp = new List<StringKeyValue>();


            higherGradePointKVTemp.Add(new StringKeyValue { Key = "A1", Value = 100 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "A2", Value = 90 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "B1", Value = 85 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "B2", Value = 80 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "B3", Value = 75 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "C1", Value = 70 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "C2", Value = 65 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "C3", Value = 60 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "D1", Value = 55 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "D2", Value = 50 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "D3", Value = 45 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "E,F,NG", Value = 0 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "Pass", Value = 30 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "Merit", Value = 50 });
            higherGradePointKVTemp.Add(new StringKeyValue { Key = "Distinction", Value = 70 });


            higherGradePointKV = higherGradePointKVTemp;
        }


    }
}

This is the View at present where just one Item Source is specified via the xaml:

<Page x:Class="LC_Points.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:local="using:LC_Points"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
      DataContext="{Binding Source={StaticResource Locator}}"
      mc:Ignorable="d">



    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="40*" />
            <RowDefinition Height="20*" />
            <RowDefinition Height="30*" />
            <RowDefinition Height="30*" />
            <RowDefinition Height="20*" />
            <RowDefinition Height="20*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="4*" />
            <ColumnDefinition Width="3*" />
            <ColumnDefinition Width="2*" />
        </Grid.ColumnDefinitions>

        <!--  TitlePanel contains the name of the application and page title  -->
        <StackPanel x:Name="TitlePanel"
                    Grid.Row="0"
                    Margin="12,17,0,28">
            <TextBlock Style="{StaticResource SubheaderTextBlockStyle}" Text="LC POINTS" />
            <TextBlock Margin="9,-7,0,0"
                       Foreground="DarkGreen"
                       Style="{StaticResource HeaderTextBlockStyle}"
                       Text="Home" />
        </StackPanel>

        <ComboBox x:Name="gradeCmbBx"
                  Grid.Row="1"
                  Grid.Column="0"
                  Grid.ColumnSpan="2"
                  Width="60"
                  HorizontalAlignment="Right"
                  DisplayMemberPath="Key"
                  ItemsSource="{Binding ordinaryGradePointKV}" />


        <ToggleButton x:Name="higherTglBtn"
                      Grid.Row="3"
                      HorizontalAlignment="Left"
                      Content="Higher"
                      IsChecked="{Binding IsHigherToggled,
                                          Mode=TwoWay}" />
        <ToggleButton x:Name="ordinaryTglBtn"
                      Grid.Row="3"
                      Grid.ColumnSpan="2"
                      HorizontalAlignment="Center"
                      Content="Ordinary"
                      IsChecked="{Binding IsOrdinaryToggled,
                                          Mode=TwoWay}" />

    </Grid>


</Page>

Solution

  • Use the Triggers property on a custom style of the combo box to change the source.

     <ComboBox
         Grid.Row="1"
         Grid.Column="0"
         Grid.ColumnSpan="2"
         Width="60"
         HorizontalAlignment="Right"
         DisplayMemberPath="Key">
         <ComboBox.Style>
             <Style>
                 <Setter Property="ComboBox.ItemsSource" Value="{Binding ordinaryGradePointKV}"></Setter>
                 <Style.Triggers>
                     <DataTrigger Binding="{Binding IsHigherToggled}" Value="True">
                         <Setter Property="ComboBox.ItemsSource"
                             Value="{Binding higherGradePointKV}" />
                     </DataTrigger>
                 </Style.Triggers>
             </Style>
         </ComboBox.Style>
     </ComboBox>