你必须建立它到您的模板。我建议为你的数据创建一个自定义的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>
然后,在你的用户控件的代码隐藏,声明一个DependencyProperty(你可以使用代码片段“propdp”):
public bool HasBeenRead
{
get { return (bool)GetValue(HasBeenReadProperty); }
set { SetValue(HasBeenReadProperty, value); OnHasBeenReadChanged(this, value); }
}
// Using a DependencyProperty as the backing store for HasBeenRead. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HasBeenReadProperty =
DependencyProperty.Register("HasBeenRead", typeof(bool), typeof(MyNewUserControl), new PropertyMetadata(false, OnHasBeenReadChanged));
然后,创建你的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);
}
}
这应该负荷正常,尤其是与默认值是假的,但万一没有,你可能需要在勾到控件的Loaded事件和的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>
哦!实际上有一个更多的事情要做。您的ListView必须告诉该项目它已被选中!添加一个SelectionChanged EventHandler(它基本上会为你生成一个)。
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(sender != null && sender is ListView)
{
if(e.AddedItems.Count > 0)
(e.AddedItems[0] as MyDataOrDataVMClass).HasBeenRead = true;
}
}
您的Data/VM类将需要实现INotifyPropertyChanged。如果您使用的是数据虚拟机,则应该已经这样做了。
快乐编码!
对不起。当你说: 'set {SetValue(HasBeenReadProperty,value); OnHasBeenReadChanged(this,value); }' Visual Studio似乎不允许带有这些参数的'OnHasBeenReadChanged'。 另一件事情正在发生,当选择改变时,HasBeenRead设置器从不被调用,尽管我的Item HasBeenRead属性设置器被调用。 此外,在该故事板上,可见性总是折叠。这样好吗?感谢您的帮助! P.S.我正在使用Caliburn for MVVM,不知道它是否妨碍了... – Silva 2013-08-28 14:41:01