如何用VisualStateManager代替DataTrigger实现动态绑定?
How to use VisualStateManager instead of DataTrigger to implement dynamic binding?
我尝试实现 DataTrigger,以根据视图中切换的切换按钮执行动态绑定。但是在搜索这个问题后,DataTrigger in WinRT? 似乎 Windows 通用应用程序中不可用,应该使用 VisualStateManager。
我的问题是,如何使用 VisualStateManager 实现与以下代码等效的代码?或者任何其他替代方法来设置视图模型代码后面的属性的动态绑定。
这是我在 运行 解决这个问题之前打算使用的 XAML,其中默认绑定是 OrdinaryGradePointKV
并且当切换按钮切换时绑定被更改到 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>
精简版的 VM 如下所示,显示了绑定的属性:
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;
}
}
}
如果您想坚持使用 DataTriggers,您可以使用 Microsoft.Xaml.Interactions.Core 命名空间中的 DataTriggerBehavior。添加行为的最简单方法是在 Blend 中打开项目并从资产窗格中添加它们。 Blend 会自动将 BehaviorsXamlSDKManaged 引用添加到项目中。
<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>
这对于您在这里的使用可能比使用视觉状态更有意义。
如果您想移动到视觉状态,则可以将视觉状态添加到普通和高级状态的页面,并让这些状态为 ComboBox 的 ItemsSource 设置动画。假设默认绑定是普通的,您的 VisualStateGroup 可能看起来像这样:
<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>
您可以通过代码触发 VisualState 或使用行为触发 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>
我尝试实现 DataTrigger,以根据视图中切换的切换按钮执行动态绑定。但是在搜索这个问题后,DataTrigger in WinRT? 似乎 Windows 通用应用程序中不可用,应该使用 VisualStateManager。
我的问题是,如何使用 VisualStateManager 实现与以下代码等效的代码?或者任何其他替代方法来设置视图模型代码后面的属性的动态绑定。
这是我在 运行 解决这个问题之前打算使用的 XAML,其中默认绑定是 OrdinaryGradePointKV
并且当切换按钮切换时绑定被更改到 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>
精简版的 VM 如下所示,显示了绑定的属性:
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;
}
}
}
如果您想坚持使用 DataTriggers,您可以使用 Microsoft.Xaml.Interactions.Core 命名空间中的 DataTriggerBehavior。添加行为的最简单方法是在 Blend 中打开项目并从资产窗格中添加它们。 Blend 会自动将 BehaviorsXamlSDKManaged 引用添加到项目中。
<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>
这对于您在这里的使用可能比使用视觉状态更有意义。
如果您想移动到视觉状态,则可以将视觉状态添加到普通和高级状态的页面,并让这些状态为 ComboBox 的 ItemsSource 设置动画。假设默认绑定是普通的,您的 VisualStateGroup 可能看起来像这样:
<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>
您可以通过代码触发 VisualState 或使用行为触发 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>