为什么我的 VisualStateTrigger 没有更新?
Why is my VisualStateTrigger not updating?
我有以下情况:
我有一个包含两个列表视图的拆分视图。左边的项目选择触发右边的内容。如果 window-宽度小于 960px,我想根据左列表视图选择隐藏其中一个列表。
宽度大于 960 像素:
|1|2|
小于 960px 且 selectedIndex == -1
|1|
小于 960px 且 selectedIndex >= 0
|2|
我的方法是通过转换器来完成:
class WindowStateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
//Debugger.Break();
if (Window.Current.Bounds.Width > 960) return 1;
if ((int)value == -1) return -1;
else return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{ throw new NotImplementedException(); }
}
在我的 xaml 中,我以这种方式使用在 NuGet 上找到的 WindowsStateTriggers 库中的 CompareStateTrigger:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
EntranceNavigationTransitionInfo.IsTargetElement="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="wideView">
<VisualState.StateTriggers>
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Converter={StaticResource wsc}, Mode=OneWay}"
CompareTo="1" Comparison="Equal"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="360"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowDetailView">
<VisualState.StateTriggers>
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Converter={StaticResource wsc}, Mode=OneWay}"
CompareTo="0" Comparison="Equal"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="0"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowListView">
<VisualState.StateTriggers>
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Converter={StaticResource wsc}, Mode=OneWay}"
CompareTo="-1" Comparison="Equal"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="*"/>
<Setter Target="DetailColumn.Width" Value="0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ListColumn" Width="0"/>
<ColumnDefinition x:Name="DetailColumn" Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="SelectionList"
Background="LightBlue"
Grid.Column="0"/>
<ListView x:Name="DetailsList"
Background="LightGreen"
Grid.Column="1"/>
</Grid>
开始时,这工作正常,但是当我在运行时更改 Window-Size 时,没有任何反应。我什至将 Debbuger.Break() 放在我的转换器中以检查它是否执行某些操作,但它没有执行。您有解决方案吗?
编辑:
我遵循了 CompositeStateTrigger 的描述,我的 XAML 现在看起来像这样:
<Page
x:Class="UWPTicketverwaltung.Views.OverviewPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWPTicketverwaltung.Views"
xmlns:triggers="using:WindowsStateTriggers"
xmlns:converters="using:UWPTicketverwaltung.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<converters:WidthConverter x:Key="screenWidth"/>
</ResourceDictionary>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
EntranceNavigationTransitionInfo.IsTargetElement="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="wideAll">
<VisualState.StateTriggers>
<triggers:AdaptiveTrigger MinWindowHeight="960"/>
<!--<triggers:CompareStateTrigger Value="{x:Bind Converter={StaticResource screenWidth}, Mode=OneWay}"
CompareTo="959" Comparison="GreaterThan"/>-->
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="360"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowOverview">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}"
CompareTo="-1" Comparison="Equal"/>
<triggers:CompareStateTrigger Value="{x:Bind Converter={StaticResource screenWidth}, Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="*"/>
<Setter Target="DetailColumn.Width" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowDetails">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}"
CompareTo="-1" Comparison="GreaterThan"/>
<triggers:CompareStateTrigger Value="{x:Bind Converter={StaticResource screenWidth}, Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="0"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ListColumn" Width="360"/>
<ColumnDefinition x:Name="DetailColumn" Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="SelectionList"
Background="LightBlue"
Grid.Column="0"/>
<ListView x:Name="DetailsList"
Background="LightGreen"
Grid.Column="1"/>
</Grid>
</Page>
我的 WidthConverter 看起来像这样:
public class WidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{ /*Debugger.Break();*/ return Window.Current.Bounds.Width; }
public object ConvertBack(object value, Type targetType, object parameter, string language)
{ throw new NotImplementedException(); }
}
开始时一切正常,但是当我更改 window-size 时,触发器不会触发。知道我做错了什么吗?此外,我的转换器仅在启动时触发一次。
编辑 2:
我按照说明将第二个 CompareStateTrigger 绑定到 Grid.Width。这是我的 XAML,它不再使用转换器:
<Grid x:Name="MainGrid"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
EntranceNavigationTransitionInfo.IsTargetElement="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="wideAll">
<VisualState.StateTriggers>
<triggers:CompareStateTrigger Value="{x:Bind MainGrid.Width, Mode=OneWay}"
CompareTo="959" Comparison="GreaterThan"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="420"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowOverview">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}"
CompareTo="-1" Comparison="Equal"/>
<triggers:CompareStateTrigger Value="{x:Bind MainGrid.Width, Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="*"/>
<Setter Target="DetailColumn.Width" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowDetails">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}"
CompareTo="-1" Comparison="GreaterThan"/>
<triggers:CompareStateTrigger Value="{x:Bind MainGrid.Width, Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="0"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ListColumn" Width="420"/>
<ColumnDefinition x:Name="DetailColumn" Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="SelectionList"
Background="LightBlue"
Grid.Column="0">
<!--<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>-->
</ListView>
<ListView x:Name="DetailsList"
Background="LightGreen"
Grid.Column="1"/>
</Grid>
现在的问题是,Width-属性 似乎根本没有被使用,因为唯一选择的状态是 "narrowOverview"(即使应用程序开始宽度大于 960)。绑定到Grid.Width的方式是不是错了?
为此使用 CompositeStateTrigger。这是一个 link
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="MainGrid">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="wideAll">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex,Mode=OneWay}"
CompareTo="-1" Comparison="GreaterThan"/>
<triggers:CompareStateTrigger Value="{x:Bind PageViewModel.ScreenWidth,Mode=OneWay}"
CompareTo="960" Comparison="GreaterThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="420"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
<!--blue-->
<VisualState x:Name="narrowOverview">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex,Mode=OneWay}"
CompareTo="-1" Comparison="Equal"/>
<triggers:CompareStateTrigger Value="{x:Bind PageViewModel.ScreenWidth,Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="*"/>
<Setter Target="DetailColumn.Width" Value="0"/>
</VisualState.Setters>
</VisualState>
<!--Green-->
<VisualState x:Name="narrowDetails">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex,Mode=OneWay}"
CompareTo="-1" Comparison="GreaterThan"/>
<triggers:CompareStateTrigger Value="{x:Bind PageViewModel.ScreenWidth,Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="0"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ListColumn" Width="420"/>
<ColumnDefinition x:Name="DetailColumn" Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="SelectionList"
Background="LightBlue"
Grid.Column="0" >
</ListView>
<ListView x:Name="DetailsList"
Background="LightGreen"
Grid.Column="1" />
</Grid>
Mainpage.xaml.cs
在此处定义 ViewModel 属性。在构造函数中将 Vm 分配给 DataContext
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
ViewModel viewModel;
public ViewModel PageViewModel
{
get
{
return viewModel;
}
set
{
if(viewModel!=value)
{
viewModel= value;
OnPropertyChanged("PageViewModel");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
// the new Null-conditional Operators are thread-safe:
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public MainPage()
{
this.SizeChanged += MainPage_SizeChanged;
PageViewModel=(ViewModel) DataContext;
}
private void MainPage_SizeChanged(object sender, SizeChangedEventArgs e)
{
PageViewModel.ScreenWidth =(int) Window.Current.Bounds.Width;
Debug.WriteLine(Vm.ScreenWidth);
}
}
Class1.cs
public class ViewModel:INotifyPropertyChanged
{
int screenWidth;
public int ScreenWidth
{
get
{
return screenWidth;
}
set
{
if(value!=screenWidth)
{
screenWidth = value;
OnPropertyChanged("ScreenWidth");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
// the new Null-conditional Operators are thread-safe:
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我有以下情况: 我有一个包含两个列表视图的拆分视图。左边的项目选择触发右边的内容。如果 window-宽度小于 960px,我想根据左列表视图选择隐藏其中一个列表。
宽度大于 960 像素:
|1|2|
小于 960px 且 selectedIndex == -1
|1|
小于 960px 且 selectedIndex >= 0
|2|
我的方法是通过转换器来完成:
class WindowStateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
//Debugger.Break();
if (Window.Current.Bounds.Width > 960) return 1;
if ((int)value == -1) return -1;
else return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{ throw new NotImplementedException(); }
}
在我的 xaml 中,我以这种方式使用在 NuGet 上找到的 WindowsStateTriggers 库中的 CompareStateTrigger:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
EntranceNavigationTransitionInfo.IsTargetElement="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="wideView">
<VisualState.StateTriggers>
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Converter={StaticResource wsc}, Mode=OneWay}"
CompareTo="1" Comparison="Equal"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="360"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowDetailView">
<VisualState.StateTriggers>
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Converter={StaticResource wsc}, Mode=OneWay}"
CompareTo="0" Comparison="Equal"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="0"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowListView">
<VisualState.StateTriggers>
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Converter={StaticResource wsc}, Mode=OneWay}"
CompareTo="-1" Comparison="Equal"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="*"/>
<Setter Target="DetailColumn.Width" Value="0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ListColumn" Width="0"/>
<ColumnDefinition x:Name="DetailColumn" Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="SelectionList"
Background="LightBlue"
Grid.Column="0"/>
<ListView x:Name="DetailsList"
Background="LightGreen"
Grid.Column="1"/>
</Grid>
开始时,这工作正常,但是当我在运行时更改 Window-Size 时,没有任何反应。我什至将 Debbuger.Break() 放在我的转换器中以检查它是否执行某些操作,但它没有执行。您有解决方案吗?
编辑:
我遵循了 CompositeStateTrigger 的描述,我的 XAML 现在看起来像这样:
<Page
x:Class="UWPTicketverwaltung.Views.OverviewPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWPTicketverwaltung.Views"
xmlns:triggers="using:WindowsStateTriggers"
xmlns:converters="using:UWPTicketverwaltung.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<converters:WidthConverter x:Key="screenWidth"/>
</ResourceDictionary>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
EntranceNavigationTransitionInfo.IsTargetElement="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="wideAll">
<VisualState.StateTriggers>
<triggers:AdaptiveTrigger MinWindowHeight="960"/>
<!--<triggers:CompareStateTrigger Value="{x:Bind Converter={StaticResource screenWidth}, Mode=OneWay}"
CompareTo="959" Comparison="GreaterThan"/>-->
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="360"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowOverview">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}"
CompareTo="-1" Comparison="Equal"/>
<triggers:CompareStateTrigger Value="{x:Bind Converter={StaticResource screenWidth}, Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="*"/>
<Setter Target="DetailColumn.Width" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowDetails">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}"
CompareTo="-1" Comparison="GreaterThan"/>
<triggers:CompareStateTrigger Value="{x:Bind Converter={StaticResource screenWidth}, Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="0"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ListColumn" Width="360"/>
<ColumnDefinition x:Name="DetailColumn" Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="SelectionList"
Background="LightBlue"
Grid.Column="0"/>
<ListView x:Name="DetailsList"
Background="LightGreen"
Grid.Column="1"/>
</Grid>
</Page>
我的 WidthConverter 看起来像这样:
public class WidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{ /*Debugger.Break();*/ return Window.Current.Bounds.Width; }
public object ConvertBack(object value, Type targetType, object parameter, string language)
{ throw new NotImplementedException(); }
}
开始时一切正常,但是当我更改 window-size 时,触发器不会触发。知道我做错了什么吗?此外,我的转换器仅在启动时触发一次。
编辑 2:
我按照说明将第二个 CompareStateTrigger 绑定到 Grid.Width。这是我的 XAML,它不再使用转换器:
<Grid x:Name="MainGrid"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
EntranceNavigationTransitionInfo.IsTargetElement="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="wideAll">
<VisualState.StateTriggers>
<triggers:CompareStateTrigger Value="{x:Bind MainGrid.Width, Mode=OneWay}"
CompareTo="959" Comparison="GreaterThan"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="420"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowOverview">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}"
CompareTo="-1" Comparison="Equal"/>
<triggers:CompareStateTrigger Value="{x:Bind MainGrid.Width, Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="*"/>
<Setter Target="DetailColumn.Width" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="narrowDetails">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}"
CompareTo="-1" Comparison="GreaterThan"/>
<triggers:CompareStateTrigger Value="{x:Bind MainGrid.Width, Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="0"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ListColumn" Width="420"/>
<ColumnDefinition x:Name="DetailColumn" Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="SelectionList"
Background="LightBlue"
Grid.Column="0">
<!--<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>-->
</ListView>
<ListView x:Name="DetailsList"
Background="LightGreen"
Grid.Column="1"/>
</Grid>
现在的问题是,Width-属性 似乎根本没有被使用,因为唯一选择的状态是 "narrowOverview"(即使应用程序开始宽度大于 960)。绑定到Grid.Width的方式是不是错了?
为此使用 CompositeStateTrigger。这是一个 link
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="MainGrid">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="wideAll">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex,Mode=OneWay}"
CompareTo="-1" Comparison="GreaterThan"/>
<triggers:CompareStateTrigger Value="{x:Bind PageViewModel.ScreenWidth,Mode=OneWay}"
CompareTo="960" Comparison="GreaterThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="420"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
<!--blue-->
<VisualState x:Name="narrowOverview">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex,Mode=OneWay}"
CompareTo="-1" Comparison="Equal"/>
<triggers:CompareStateTrigger Value="{x:Bind PageViewModel.ScreenWidth,Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="*"/>
<Setter Target="DetailColumn.Width" Value="0"/>
</VisualState.Setters>
</VisualState>
<!--Green-->
<VisualState x:Name="narrowDetails">
<VisualState.StateTriggers>
<triggers:CompositeStateTrigger Operator="And">
<triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex,Mode=OneWay}"
CompareTo="-1" Comparison="GreaterThan"/>
<triggers:CompareStateTrigger Value="{x:Bind PageViewModel.ScreenWidth,Mode=OneWay}"
CompareTo="960" Comparison="LessThan"/>
</triggers:CompositeStateTrigger>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ListColumn.Width" Value="0"/>
<Setter Target="DetailColumn.Width" Value="*"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ListColumn" Width="420"/>
<ColumnDefinition x:Name="DetailColumn" Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="SelectionList"
Background="LightBlue"
Grid.Column="0" >
</ListView>
<ListView x:Name="DetailsList"
Background="LightGreen"
Grid.Column="1" />
</Grid>
Mainpage.xaml.cs
在此处定义 ViewModel 属性。在构造函数中将 Vm 分配给 DataContext
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
ViewModel viewModel;
public ViewModel PageViewModel
{
get
{
return viewModel;
}
set
{
if(viewModel!=value)
{
viewModel= value;
OnPropertyChanged("PageViewModel");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
// the new Null-conditional Operators are thread-safe:
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public MainPage()
{
this.SizeChanged += MainPage_SizeChanged;
PageViewModel=(ViewModel) DataContext;
}
private void MainPage_SizeChanged(object sender, SizeChangedEventArgs e)
{
PageViewModel.ScreenWidth =(int) Window.Current.Bounds.Width;
Debug.WriteLine(Vm.ScreenWidth);
}
}
Class1.cs
public class ViewModel:INotifyPropertyChanged {
int screenWidth;
public int ScreenWidth
{
get
{
return screenWidth;
}
set
{
if(value!=screenWidth)
{
screenWidth = value;
OnPropertyChanged("ScreenWidth");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
// the new Null-conditional Operators are thread-safe:
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}