2013-05-10 57 views
1

我有一个ListView,它有一个ItemTemplateSelector,它根据从服务中获取的数据选择一个模板。在这种情况下,它是具有读取与未读状态的项目列表。选择器在加载时工作良好,但是如何在用户单击该项目时更改模板?很显然,我希望模板在用户“读取”数据时进行更改。Windows Store应用程序更改项目模板OnClick /动态

View.xaml:

<Page.Resources> 
    <selectors:MyItemTemplateSelector x:Key="NoteItemTemplateSelector" 
             ReadTemplate="{StaticResource MyReadTemplate}" 
             UnreadTemplate="{StaticResource MyUnreadTemplate}"/> 
</Page.Resources> 

<ListView x:Name="ListView1" 
     ItemTemplateSelector="{StaticResource MyItemTemplateSelector}"/> 

回答

1

你必须建立它到您的模板。我建议为你的数据创建一个自定义的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。如果您使用的是数据虚拟机,则应该已经这样做了。

快乐编码!

+0

对不起。当你说: '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

相关问题