C# Windows应用商店应用程序更改项模板OnClick/dynamicly
我有一个ListView,它有一个ItemTemplateSelector,它根据从服务获取的数据选择模板。在本例中,它是一个具有“已读”与“未读”状态的项目列表。选择器在加载时运行良好,但是当用户单击该项时,如何更改模板?显然,我希望在用户“读取”数据时更改模板 View.xaml:C# Windows应用商店应用程序更改项模板OnClick/dynamicly,c#,windows-store-apps,winrt-xaml,C#,Windows Store Apps,Winrt Xaml,我有一个ListView,它有一个ItemTemplateSelector,它根据从服务获取的数据选择模板。在本例中,它是一个具有“已读”与“未读”状态的项目列表。选择器在加载时运行良好,但是当用户单击该项时,如何更改模板?显然,我希望在用户“读取”数据时更改模板 View.xaml: <Page.Resources> <selectors:MyItemTemplateSelector x:Key="NoteItemTemplateSelector"
<Page.Resources>
<selectors:MyItemTemplateSelector x:Key="NoteItemTemplateSelector"
ReadTemplate="{StaticResource MyReadTemplate}"
UnreadTemplate="{StaticResource MyUnreadTemplate}"/>
</Page.Resources>
<ListView x:Name="ListView1"
ItemTemplateSelector="{StaticResource MyItemTemplateSelector}"/>
您必须将其构建到模板中。我建议为您的数据创建一个自定义UserControl,当单击/点击/选择时,它会隐藏“未读”版本并显示“已读”版本。可以将起始状态绑定到数据本身,也可以绑定到数据的ViewModel。比如:
<UserControl xmlns...>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DisplayStates">
<VisualState x:Name="Read">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ReadContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="UnreadContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unread">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="UnreadContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ReadContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name:"UnreadContent">
<!--What it looks like when Unread-->
</Grid>
<Grid x:Name:"ReadContent">
<!--What it looks like when Unread-->
</Grid>
</Grid>
</UserControl>
然后,创建PropertyChanged方法来切换视觉状态
private static void OnHasBeenReadChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ((bool)e.NewValue)
{
VisualStateManager.GoToState(d as Control, "Read", true);
}
else
{
VisualStateManager.GoToState(d as Control, "Unread", true);
}
}
这应该正确加载,特别是在默认值为false的情况下,但如果不是,您可能需要挂接到控件的已加载事件,并从那里将VisualState设置为未读
最后,您只需要一个项目模板,因此请去掉选择器,只需执行以下操作:
<ListView.ItemTemplate>
<DataTemplate>
<!-- You'll have to import the namespace. Also, assumes that the item -->
<!-- (or Item VM) has a "HasBeenRead" bool property -->
<namespacewheremycontrolis:MyReadUnreadControl HasBeenRead="{Binding HasBeenRead}"/>
</DataTemplate>
</ListView.ItemTemplate>
您的Data/VM类将需要实现INotifyPropertyChanged。如果您使用的是数据虚拟机,它应该已经做到了这一点
快乐编码 您必须将其构建到模板中。我建议为您的数据创建一个自定义UserControl,当单击/点击/选择时,它会隐藏“未读”版本并显示“已读”版本。可以将起始状态绑定到数据本身,也可以绑定到数据的ViewModel。比如:
<UserControl xmlns...>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DisplayStates">
<VisualState x:Name="Read">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ReadContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="UnreadContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unread">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="UnreadContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ReadContent">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name:"UnreadContent">
<!--What it looks like when Unread-->
</Grid>
<Grid x:Name:"ReadContent">
<!--What it looks like when Unread-->
</Grid>
</Grid>
</UserControl>
然后,创建PropertyChanged方法来切换视觉状态
private static void OnHasBeenReadChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ((bool)e.NewValue)
{
VisualStateManager.GoToState(d as Control, "Read", true);
}
else
{
VisualStateManager.GoToState(d as Control, "Unread", true);
}
}
这应该正确加载,特别是在默认值为false的情况下,但如果不是,您可能需要挂接到控件的已加载事件,并从那里将VisualState设置为未读
最后,您只需要一个项目模板,因此请去掉选择器,只需执行以下操作:
<ListView.ItemTemplate>
<DataTemplate>
<!-- You'll have to import the namespace. Also, assumes that the item -->
<!-- (or Item VM) has a "HasBeenRead" bool property -->
<namespacewheremycontrolis:MyReadUnreadControl HasBeenRead="{Binding HasBeenRead}"/>
</DataTemplate>
</ListView.ItemTemplate>
您的Data/VM类将需要实现INotifyPropertyChanged。如果您使用的是数据虚拟机,它应该已经做到了这一点
快乐编码 抱歉耽搁了。当您说:
set{SetValue(hasbeenredproperty,value);onhasbeenredchange(this,value);}
Visual Studio似乎不允许使用这些参数设置onhasbeenredchange
。另一件事正在发生,当选择更改时,HasBeenRead setter从未被调用,尽管正在调用我的项目HasBeenRead属性setter。此外,在该情节提要上,可见性始终处于折叠状态。可以吗?谢谢你的帮助!另外,我正在使用Caliburn的MVVM,不知道它是否会妨碍…抱歉,耽搁了。当您说:set{SetValue(hasbeenredproperty,value);onhasbeenredchange(this,value);}
Visual Studio似乎不允许使用这些参数设置onhasbeenredchange
。另一件事正在发生,当选择更改时,HasBeenRead setter从未被调用,尽管正在调用我的项目HasBeenRead属性setter。此外,在该情节提要上,可见性始终处于折叠状态。可以吗?谢谢你的帮助!另外,我正在使用Caliburn作为MVVM,不知道它是否会妨碍。。。