0

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>
Brian Var
  • 6,029
  • 25
  • 114
  • 212

1 Answers1

1

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>
Cyral
  • 13,999
  • 6
  • 50
  • 90
  • Okay in this case I need to set `higherGradePointKV` if `IsOrdinaryToggled` , do I just need to set up a second style? could you show that implementation please – Brian Var May 06 '15 at 23:42
  • Just swap the ItemsSource bindings in that case, the first is default, and the trigger will override it when IsHigherToggled is true. – Cyral May 06 '15 at 23:53
  • Right I see what your doing there, that should work perfect, I'll test later and report on the results. – Brian Var May 06 '15 at 23:56
  • Just pasted that ^^ in, and got an error on `Triggers` "Error 2 The attachable property 'Triggers' was not found in type 'Style'" and on `DataTrigger` "The type DataTrigger was not found" Any ideas how to resolve that? If I do an intellisense on Style. I get the options "BasedOn , Setters, TargetType" no Triggers though. This is a Win RT project btw if that has anyone weight on this error. – Brian Var May 07 '15 at 00:07
  • Hmm, apparently DataTrigger is not available on WinRT, see [this](http://stackoverflow.com/q/7439532/1218281) question. (Seems there are alternatives too). You could always create a property with a getter that returns the correct list. – Cyral May 07 '15 at 00:14
  • Not sure how I would implement the property to solve this, could you give a code snippet on that type of solution? – Brian Var May 07 '15 at 13:34
  • Try something like `public List GradePointKV { get { return IsOrdinaryToggled ? ordinaryGradePointKV : higherGradePointKV; } }` Make sure to raise a property change event inside your `IsOrdinaryToggled` and `IsHigherToggled` setters so WPF knows to update the binding. (Like `RaisePropertyChanged("GradePointKV")` – Cyral May 07 '15 at 17:09
  • Cool came across the a similar solution when searching, this is my implementation of that. http://hastebin.com/wirageyaso.cs Just testing now.. – Brian Var May 07 '15 at 17:32
  • I see now that I need to ^ `RaisePropertyChanged` on the binding shell `GradePointKV ` binding property also – Brian Var May 07 '15 at 17:35
  • The property solution worked, Cheers! maybe you could update your answer so that its relevant to Win RT and other users searching the same issue? – Brian Var May 07 '15 at 17:41