简体   繁体   中英

How to change visibility of a textblock based on the tap event using only XAML

I have a listview showing a list of images. Images are flags of different nations. And on clicking a flag, name of the country shown be shown. ONLY NAME OF THAT PARTICULAR COUNTRY.

What I did:

Defined a List View. Contents are added to the List View using Data Binding. List View has an Image & a TextBlock. TextBlock is kept collapsed initially.

I used Behaviours SDK to change the visibility of the TextBlock on Tap event of the Grid. So when I tap on a India's flag image, that corresponding country's name (India) is shown. And when I tap on France's flag, France is displayed on TextBlock.

Here's a screenshot:

在此输入图像描述

Only the name of the flag that was last clicked should be shown. Instead of showing names of al flags that were clicked.

Curently, when Indian flag is clicked, India is shown. And when I click Denmark's flag, the TextBlock doesn't get hidden from India's grid. Instead both the TextBlocks are remaining visible.

<ListView ItemsSource="{Binding CountryDetails}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <i:Interaction.Behaviors>
                            <ic:EventTriggerBehavior EventName="Tapped">
                                <ic:ChangePropertyAction TargetObject="{Binding ElementName=countryName}" PropertyName="Visibility" Value="Visible"/>
                            </ic:EventTriggerBehavior>
                        </i:Interaction.Behaviors>
                        <Image Source="{Binding flagImages}" CacheMode="BitmapCache">
                        </Image>
                        <TextBlock Visibility="Collapsed" Name="countryName" Text="{Binding countryTitle}"></TextBlock>                        
                    </Grid>                    
                </DataTemplate>
            </ListView.ItemTemplate>
</ListView>

WHAT I AM TRYING TO ACHIEVE IS THIS:

在此输入图像描述

Any help or suggestions would be great. Thank you.

Here's a way, but it mightn't be as nice as code-behind or in the view model.

<ListView x:Name="lv">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <i:Interaction.Behaviors>
                    <icore:DataTriggerBehavior Binding="{Binding ElementName=lv, Path=SelectedValue}" Value="{Binding}" ComparisonCondition="Equal">
                        <icore:ChangePropertyAction TargetObject="{Binding ElementName=tb}" PropertyName="Visibility" Value="Visible" />
                    </icore:DataTriggerBehavior>
                    <icore:DataTriggerBehavior Binding="{Binding ElementName=lv, Path=SelectedValue}" Value="{Binding}" ComparisonCondition="NotEqual">
                        <icore:ChangePropertyAction TargetObject="{Binding ElementName=tb}" PropertyName="Visibility" Value="Collapsed" />
                    </icore:DataTriggerBehavior>
                </i:Interaction.Behaviors>

                <Image Source="/Assets/Logo.png" />
                <TextBlock x:Name="tb" Grid.Column="2" Visibility="Collapsed" FontSize="20" Text="{Binding}" VerticalAlignment="Center" Margin="10,0,0,0" />
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>

    <ListView.Items>
        <x:String>Australia</x:String>
        <x:String>Italy</x:String>
        <x:String>France</x:String>
        <x:String>USA</x:String>
        <x:String>China</x:String>
        <x:String>Japan</x:String>
        <x:String>Sweden</x:String>
    </ListView.Items>
</ListView>

截图


The example I've given above is very basic, but most likely you've bound the page to your view model and bound the list view's ItemsSource to a property on the view model (most likely an ObservableCollection of strings or a custom type). In this case, make sure you update the bindings accordingly:

<ListView x:Name="lv" ItemsSource="{Binding Items}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <i:Interaction.Behaviors>
                    <!-- Must compare strings otherwise DataTriggerBehavior complains -->
                    <icore:DataTriggerBehavior Binding="{Binding ElementName=lv, Path=SelectedValue.Name}" Value="{Binding Name}" ComparisonCondition="Equal">
                        <icore:ChangePropertyAction TargetObject="{Binding ElementName=tb}" PropertyName="Visibility" Value="Visible" />
                    </icore:DataTriggerBehavior>
                    <icore:DataTriggerBehavior Binding="{Binding ElementName=lv, Path=SelectedValue.Name}" Value="{Binding Name}" ComparisonCondition="NotEqual">
                        <icore:ChangePropertyAction TargetObject="{Binding ElementName=tb}" PropertyName="Visibility" Value="Collapsed" />
                    </icore:DataTriggerBehavior>
                </i:Interaction.Behaviors>

                <Image Source="/Assets/Logo.png" />
                <TextBlock x:Name="tb" Grid.Column="2" Visibility="Collapsed" FontSize="20" Text="{Binding Name}" VerticalAlignment="Center" Margin="10,0,0,0" />
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

where Items is an ObservableCollection<Country> and

public class Country
{
    public string Name { get; set; }
}

An alternate approach to using triggers would be to set the ItemContainerStyle . This lets you override the ControlTemplate on the ListViewItem s, which in turn gives you access to the "Selected" visual state. You can use that to show the country name text element:

<ListView ItemsSource="{Binding CountryDetails}">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="ControlTemplate">
                <Setter.Value>
                    <ControlTemplate TargetType="ListViewItem">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Selected">                                    
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames
                                                 Storyboard.TargetName="countryName"
                                                 Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />

                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>

                            <Image Source="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content.flagImages}" CacheMode="BitmapCache" />
                            <TextBlock Visibility="Collapsed" Name="countryName" Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content.countryTitle}"></TextBlock>                        
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
       </Style>
    </ListView.ItemContainerStyle>
</ListView>

I guess you might have to fill in some more states from the default template (or maybe copy-and-modify) -- I am not familiar with this ListView control.

Kind of crazy how difficult it is to do something so simple. I would strongly consider putting a "Selected" property in the item model, and then updating it using code behind. Sometimes all-XAML is not worth the trouble.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM