2015-12-15 35 views
0

我在UWP一個綁定列表視圖,我要顯示或隱藏基於某些屬性內綁定使用VisualStateGroup的ListView

的XAML我使用的ItemTemplate裏面的一些控制是這裏結合的ObservableCollection

<ListView x:Name="lvwMovieWatchlist" ItemsSource="{x:Bind Books}" Margin="10"> 
      <ListView.ItemsPanel> 
       <ItemsPanelTemplate> 
        <ItemsWrapGrid Orientation="Horizontal" /> 
       </ItemsPanelTemplate> 
      </ListView.ItemsPanel> 
      <ListView.ItemTemplate>    
       <DataTemplate x:DataType="data:BookModel"> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="Auto"/> 
          <ColumnDefinition Width="*"/> 
         </Grid.ColumnDefinitions> 
         <Border Width="156" Height="200"> 
          <Image Source="{Binding CoverImage}" Stretch="UniformToFill"/> 
         </Border> 
         <StackPanel Grid.Column="1" Orientation="Vertical"> 
          <TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextBlockStyle}" TextWrapping="NoWrap" Margin="9.6,0"/> 
          <TextBlock Text="{Binding Name}" Style="{StaticResource SubtitleTextBlockStyle}" TextWrapping="NoWrap" Margin="9.6,0"/> 
          <StackPanel Orientation="Horizontal" Margin="10"> 
           <Button Name="Btn_Download" Tag="{Binding}" Click="Btn_Download_Click"> DOWNLOAD</Button>         
           <Button Name="Btn_Read" Tag="{Binding}" Click="Btn_Read_Click"> READ</Button>         
          </StackPanel> 
         </StackPanel> 
        </Grid> 
       </DataTemplate>    
      </ListView.ItemTemplate> 
     </ListView> 

的2個按鈕Btn_Download和Btn_Read在這裏提問 如果狀態屬性爲「讀」的話,我想設置能見度可見的Btn_Read否則顯示Btn_Download按鈕

在WPF我有三gger爲achieveing同樣喜歡

 <DataTemplate.Triggers> 
      <DataTrigger Binding="{Binding Status}" Value="read">     
       <Setter TargetName="Btn_Read" Property="Visibility" Value="Visible"/> 
       <Setter TargetName="Btn_Download" Property="Visibility" Value="Collapsed"/>     
      </DataTrigger>            
     </DataTemplate.Triggers> 

但UWP沒有觸發僅VisualStateManager.VisualStateGroups是繳費。 所以,我如何能使其利用VisualStateGroup ItemTemplate中

回答

1

內的可能的想法是使用一個轉換器,而不是VisualStateManager:

<StackPanel Orientation="Horizontal" Margin="10"> 
             <Button Name="Btn_Download" Tag="{Binding}" Click="Btn_Download_Click" Visibility={Binding Status, Converter={StaticResource StatusToDownloadVisibilityConverter}}> DOWNLOAD</Button>         
             <Button Name="Btn_Read" Tag="{Binding}" Click="Btn_Read_Click" Visibility={Binding Status, Converter={StaticResource StatusToReadVisibilityConverter}}> READ</Button>         
    </StackPanel> 

只需創建2個轉換器(StatusToDownloadVisibilityConverter和StatusToReadVisibilityConverter),其採取現狀參數並根據Status屬性的值返回可見性。

也許不是100%理想的解決方案,但應該工作!

+0

是的,這樣可以工作,但我喜歡用VisualState製作它既然它完全控制了xaml本身,想學習VisualState的概念 –

1

如果您想完全在XAML中完成,您可以使用Interactivity behaviors擴展名來完成。使用可視狀態和datatriggeraction樣品可以是這樣的 - XAML:

<Grid xmlns:i="using:Microsoft.Xaml.Interactivity" xmlns:ic="using:Microsoft.Xaml.Interactions.Core" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup x:Name="ReadOrNot"> 
      <VisualState x:Name="Normal"/> 
      <VisualState x:Name="Read"> 
       <Storyboard BeginTime="0:0:0" Duration="0:0:1"> 
        <FadeOutThemeAnimation TargetName="BtnDownload"/> 
       </Storyboard> 
      </VisualState> 
     </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups> 
    <i:Interaction.Behaviors> 
     <i:BehaviorCollection> 
      <ic:DataTriggerBehavior Binding="{Binding Status}" Value="read"> 
       <ic:GoToStateAction StateName="Read"/> 
      </ic:DataTriggerBehavior> 
     </i:BehaviorCollection> 
    </i:Interaction.Behaviors> 
    <Button Name="BtnDownload" HorizontalAlignment="Left" Content="Download" FontSize="20" Foreground="Red"/> 
    <Button HorizontalAlignment="Center" Content="Change property" FontSize="20" Foreground="Orange" Click="Button_Click"/> 
    <Button Name="BtnRead" HorizontalAlignment="Right" Content="Read" FontSize="20" Foreground="Green"/> 
</Grid> 

後面的代碼:

public sealed partial class MainPage : Page, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    public void RaiseProperty(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 

    private string status = "notRead"; 
    public string Status 
    { 
     get { return status; } 
     set { status = value; RaiseProperty(nameof(Status)); } 
    } 

    public MainPage() 
    { 
     this.InitializeComponent(); 
     DataContext = this; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) => Status = "read"; 
} 

按鈕點擊狀態更改爲閱讀,並通過行爲觸發視覺狀態的變化。你可以爲你的項目模板做類似的事情。作爲一個方面說明,您也可以使用其他操作,根據您想要實現的操作可能會更容易 - 例如ChangePropertyAction

當然,使其工作,你必須在你的項目中添加引用行爲(添加引用 - >通用窗口 - >擴展),或通過的NuGet,什麼樣的igrali has mentioned,是一個更好的選擇(開源和靶向UWP)。

+1

我只想補充說,最好通過Nuget添加Behaviors SDK,因爲它現在針對UWP並且是開源的。 https://github.com/Microsoft/XamlBehaviors/ –

+0

@igrali你是對的。感謝您的評論。 – Romasz

0

將您的模板包裹在用戶控件中並添加可視狀態管理器。

<ListView x:Name="lvwMovieWatchlist" ItemsSource="{x:Bind ViewModel.Books}"> 
    <ListView.ItemTemplate> 
     <DataTemplate x:DataType="local:BookModel"> 
      <local:BookControl /> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

<UserControl 
    x:Class="App2.BookControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:App2" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    d:DesignHeight="300" 
    d:DesignWidth="400"> 
     <Grid> 
      <VisualStateManager.VisualStateGroups> 
       <VisualStateGroup x:Name="ButtonsVisibility"> 
        <VisualState x:Name="ButtonsVisible"> 
        </VisualState> 
        <VisualState x:Name="ButtonsHidden"> 
         <VisualState.StateTriggers> 
          <StateTrigger IsActive="{Binding Status, Mode=OneWay}" /> 
         </VisualState.StateTriggers> 
         <VisualState.Setters> 
          <Setter Target="Btn_Download.Visibility" Value="Collapsed" /> 
          <Setter Target="Btn_Read.Visibility" Value="Collapsed" /> 
         </VisualState.Setters> 
        </VisualState> 
       </VisualStateGroup> 
      </VisualStateManager.VisualStateGroups> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*"/> 
      </Grid.ColumnDefinitions> 
      <StackPanel Orientation="Vertical"> 
       <TextBlock Text="{Binding Title}" /> 
       <TextBlock Text="{Binding Subtitle}" /> 
       <StackPanel Orientation="Horizontal"> 
        <Button Name="Btn_Download" Tag="{Binding}" Click="Btn_Download_Click">DOWNLOAD</Button> 
        <Button Name="Btn_Read" Tag="{Binding}" Click="Btn_Read_Click">READ</Button> 
       </StackPanel> 
      </StackPanel> 
     </Grid> 
</UserControl> 

此示例在布爾屬性上使用內置的StateTrigger。爲了比較一個屬性的某個值,可以使用真棒WindowsStateTriggers庫中的EqualsStateTrigger(https://github.com/dotMorten/WindowsStateTriggers)。