I've tried to implement DataTrigger, to perform dynamic binding based on which toggle button is toggled in a View. But after searching on the issue, DataTrigger in WinRT? it seems this is not available in Windows Universal apps, and VisualStateManager should be used instead.
My question is, how can I implement the equivalent of the below code using the VisualStateManager? Or any other alternative to set the dynamic binding from the properties in code behind of the View Model.
This is the XAML I had intended to use until I ran into this problem, where the default binding is OrdinaryGradePointKV
and when the toggle button is toggle the binding is changed to HigherGradePointKV
:
<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>
A trimmed down version of the VM is as follows, showing the properties that are being bound:
namespace LC_Points.ViewModel
{
public class MainViewModel : ViewModelBase
{
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
//call methods to initialize list data
GetSubjectTypes();
GetOrdinaryGradePairs();
GetHigherGradePairs();
}
public List<Score> Subjects { get; set; }
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");
}
}
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;
}
public void GetSubjectTypes()
{
List<Score> subjectList = new List<Score>();
// Adding Subjects to List
subjectList.Add(new Score { Subject = "Biology" });
subjectList.Add(new Score { Subject = "Business" });
subjectList.Add(new Score { Subject = "Business Group" });
subjectList.Add(new Score { Subject = "Chemistry" });
subjectList.Add(new Score { Subject = "Classical Studies" });
Subjects = subjectList;
}
}
}
If you want to stick with DataTriggers you can use the DataTriggerBehavior from the Microsoft.Xaml.Interactions.Core namespace. The easiest way to add behaviors is to open the project in Blend and add them from the assets pane. Blend will automatically add the BehaviorsXamlSDKManaged reference to the project.
<ComboBox>
<Interactivity:Interaction.Behaviors>
<Core:DataTriggerBehavior Value="True" Binding="{Binding IsChecked, ElementName=toggleButton}">
<Core:ChangePropertyAction PropertyName="ItemsSource" Value="{Binding OrdinaryGradePointKV}"/>
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Value="False" Binding="{Binding IsChecked, ElementName=toggleButton}">
<Core:ChangePropertyAction PropertyName="ItemsSource" Value="{Binding HighGradePointKV}"/>
</Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ComboBox>
This probably makes more sense for your use here than using Visual States.
If you want to move to Visual States then you can add visual states to page for the Ordinary and Higher states and have those states animate the ComboBox's ItemsSource. Assuming the default binding is Ordinary your VisualStateGroup could look something like this:
<VisualStateGroup x:Name="GradePointStates">
<VisualState x:Name="Higher">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(ItemsControl.ItemsSource)" Storyboard.TargetName="comboBox">
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding HigherGradePointKV}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Ordinary">
</VisualState>
</VisualStateGroup>
You can either trigger the VisualState from code or by using a Behavior to trigger a GoToStateAction:
<ToggleButton Content="ToggleButton">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Checked">
<Core:GoToStateAction StateName="Higher"/>
</Core:EventTriggerBehavior>
<Core:EventTriggerBehavior EventName="Unchecked">
<Core:GoToStateAction StateName="Ordinary"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ToggleButton>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With