locked
how can I change gridview item border when pointer/mouse is over

    Question

  • below my GridView

      <Grid Grid.Column="1" Margin="80,0,0,0">
               
    <Grid.RowDefinitions>
                   
    <RowDefinition Height="50" />
                   
    <RowDefinition Height="*" />
               
    </Grid.RowDefinitions>
               
    <TextBlock Text="aktualności" Style="{StaticResource PageSubheader}" />

               
    <local:VariableGridView x:Name="listView" Grid.Row="1" Margin="0,2,0,0" IsItemClickEnabled="True" ItemClick="listView_ItemClick" >
                   
    <local:VariableGridView.ItemTemplate>
                       
    <DataTemplate>
                           
    <Grid>
                               
    <Border>
                                   
    <Image Source="Templates/LightGray.png" Stretch="UniformToFill"/>
                               
    </Border>
                               
    <StackPanel VerticalAlignment="Top" >
                                   
    <TextBlock Text="{Binding title}" Height="30" Margin="15,0,15,0"/>
                                   
    <TextBlock Text="{Binding short}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
                               
    </StackPanel>
                           
    </Grid>
                       
    </DataTemplate>
                   
    </local:VariableGridView.ItemTemplate>
                   
    <local:VariableGridView.ItemsPanel>
                       
    <ItemsPanelTemplate>
                           
    <VariableSizedWrapGrid ItemWidth="150" ItemHeight="150" Orientation="Vertical" Margin="0,0,80,0" MaximumRowsOrColumns="3"/>
                       
    </ItemsPanelTemplate>
                   
    </local:VariableGridView.ItemsPanel>
               
    </local:VariableGridView>
           
    </Grid>

    The local class (VariableGridView) is small extension for creating view like in Windows Store. It works OK. I can't do one thing. How to change border when the pointer is over the grid ITEM ? I can't find it.

    Saturday, August 18, 2012 1:32 PM

Answers

  • "That does not work":

    - When UIElements are superposed along a Z-axis, you generally need to add IsHitTestVisible='false' on the elements that are superposed on that one you want to listen pointer events upon. In your snippet, StackPanel[*] and TextBlocks are 'blocking' access to the underlying Border, since they are in the same Grid.Row and Grid.Column as the Border: they must be rendered IsHitTestVisible='false'.

    - Hence, I have inserted the original snippet within a running example that better matches your 'superposed elements' scenario.

    ---

    Should you require it, these links contains good material about incorporating VSMs in WinRT control templates:

    - http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.visualstatemanager

    - http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh465374.aspx#specifying_the_visual_behavior_of_a_control

    ---

    [*] [Advanced]

    - Setting <StackPanel IsHitTestVisible="True|False"/> is irrelevant when you do _not_ set its property Background=...: in both cases, the Border event handlers are triggered. The reason: the StackPanel Background property is 'null' by default, rendering the StackPanel not hit test visible.
    - Conversely, Setting <StackPanel IsHitTestVisible="False" Background="Transparent"/> is required [to trigger the Border event handlers] when we set its Background to a non-null value.




    Sunday, August 19, 2012 4:02 PM

All replies

  • This is the approach using VSM under Win8 RTM:

    - It contains Debug statements within the Pointer Event methods
    - Adapt the example to your UX requirements.

    ---

    <Page
        x:Class="App3.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App3"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        <Page.Resources>
            <CollectionViewSource x:Name="itemsViewSource" Source="{Binding ItemList}"/>
        </Page.Resources>
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <GridView x:Name="gridView" Grid.Row="0" Grid.Column="0" 
                      ItemsSource="{Binding Path=ItemList}" SelectionMode="Multiple" IsItemClickEnabled="True" ItemClick="gridView_ItemClick_1">
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VariableSizedWrapGrid ItemWidth="150" ItemHeight="150" Orientation="Vertical" Margin="0,0,80,0" MaximumRowsOrColumns="3"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
                <GridView.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.Resources>
                                <Style x:Key="animatedBorderStyle" TargetType="ContentControl">
                                    <Setter Property="Template">
                                        <Setter.Value>
                                            <ControlTemplate TargetType="ContentControl">
                                                <Grid>
                                                    <VisualStateManager.VisualStateGroups>
                                                        <VisualStateGroup>
                                                            <VisualState x:Name="s1">
                                                                <Storyboard>
                                                                    <DoubleAnimation FillBehavior="HoldEnd" To="1.0" Storyboard.TargetName="animatedBorder" Storyboard.TargetProperty="Opacity"/>
                                                                </Storyboard>
                                                            </VisualState>
                                                        </VisualStateGroup>
                                                    </VisualStateManager.VisualStateGroups>
                                                    <Border Background="GreenYellow" x:Name="animatedBorder" Opacity="0.0"/>
                                                </Grid>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                            </Grid.Resources>
                            <Border BorderBrush="Red" BorderThickness="1" Width="101" Height="101">
                                <ContentControl Width="100" Height="100" Style="{StaticResource animatedBorderStyle}" 
                                                PointerEntered="ContentControl_PointerEntered_1" 
                                                PointerMoved="ContentControl_PointerMoved_1"
                                                PointerExited="ContentControl_PointerExited_1"
                                                />
                            </Border>
                            <StackPanel VerticalAlignment="Top" IsHitTestVisible="False" >
                                <TextBlock Text="{Binding Path=Name}" IsHitTestVisible="False" Margin="10"/>
                                <TextBox Text="{Binding Path=Name}" IsReadOnly="True" IsHitTestVisible="False" Margin="10"/>
                                <TextBlock Text="{Binding Path=Name}" IsHitTestVisible="False" Margin="10"/>
                            </StackPanel>
                        </Grid>
                    </DataTemplate>
                </GridView.ItemTemplate>
                <GridView.ItemContainerStyle>
                    <Style TargetType="GridViewItem">
                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                        <Setter Property="VerticalContentAlignment" Value="Top"/>
                        <Setter Property="HorizontalAlignment" Value="Stretch"/>
                        <Setter Property="VerticalAlignment" Value="Top"/>
                    </Style>
                </GridView.ItemContainerStyle>
            </GridView>
            <Button Grid.Row="1" Content="Add items" Click="Button_Click_1"/>
        </Grid>
    </Page>
    

    ---

    using System.Diagnostics;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Navigation;
    
    namespace App3
    {
        /// <summary>
        /// An empty page that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class MainPage : Page
        {
            KiwiExec exec;
            int offset = 10;
            public MainPage()
            {
                this.DataContext = this.exec = new KiwiExec();
                this.exec.Init(this.offset); this.offset = this.offset + 10;
                this.InitializeComponent();
            }
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                this.offset = this.offset + 10;
                this.exec.Init(this.offset); 
            }
            private void ContentControl_PointerEntered_1(object sender, PointerRoutedEventArgs e)
            {
                // Variables
                ContentControl cc = sender as ContentControl;
                bool result;
    
                // Exec
                if (cc == null) return;
                result = VisualStateManager.GoToState((ContentControl)sender, "s1", false);
                // ...
                Debug.WriteLine("Entered:[Sender:{0}] [OriginalSource:{1}]", sender.GetType().Name, e.OriginalSource);
            }
            private void ContentControl_PointerMoved_1(object sender, PointerRoutedEventArgs e)
            {
                // Exec
                Debug.WriteLine("Moved:[Sender:{0}] [OriginalSource:{1}]", sender.GetType().Name, e.OriginalSource);
            }
            private void ContentControl_PointerExited_1(object sender, PointerRoutedEventArgs e)
            {
                // Exec
                Debug.WriteLine("Exited:[Sender:{0}] [OriginalSource:{1}]", sender.GetType().Name, e.OriginalSource);
            }
        }
    }

    ---

    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    
    namespace App3
    {
        public class KiwiExec : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            private ObservableCollection<KiwiItem> itemList = new ObservableCollection<KiwiItem>();
            public ObservableCollection<KiwiItem> ItemList
            {
                get { return itemList; }
                set { itemList = value; 
                    OnPropertyChanged("ItemList"); }
            }
            public void Init(int offset)
            {
                this.ItemList.Add(new KiwiItem { Name = String.Format("{0}", offset++) });
                this.ItemList.Add(new KiwiItem { Name = String.Format("{0}", offset++) });
                this.ItemList.Add(new KiwiItem { Name = String.Format("{0}", offset++) });
            }
        }
    }

    ---

    using System.ComponentModel;
    
    namespace App3
    {
        /// <summary>
        /// 
        /// </summary>
        public class KiwiItem
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            string name;
            public string Name
            {
                get { return name; }
                set { name = value; OnPropertyChanged("Name"); }
            }
        }
    }
    ---




    • Edited by ForInfo Monday, August 20, 2012 7:41 AM
    Sunday, August 19, 2012 8:24 AM
  • That does not work. I even set a breakpoint in the event function. When I`m over the element nothing is happening so that method isn`t invoked
    Sunday, August 19, 2012 1:37 PM
  • "That does not work":

    - When UIElements are superposed along a Z-axis, you generally need to add IsHitTestVisible='false' on the elements that are superposed on that one you want to listen pointer events upon. In your snippet, StackPanel[*] and TextBlocks are 'blocking' access to the underlying Border, since they are in the same Grid.Row and Grid.Column as the Border: they must be rendered IsHitTestVisible='false'.

    - Hence, I have inserted the original snippet within a running example that better matches your 'superposed elements' scenario.

    ---

    Should you require it, these links contains good material about incorporating VSMs in WinRT control templates:

    - http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.visualstatemanager

    - http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh465374.aspx#specifying_the_visual_behavior_of_a_control

    ---

    [*] [Advanced]

    - Setting <StackPanel IsHitTestVisible="True|False"/> is irrelevant when you do _not_ set its property Background=...: in both cases, the Border event handlers are triggered. The reason: the StackPanel Background property is 'null' by default, rendering the StackPanel not hit test visible.
    - Conversely, Setting <StackPanel IsHitTestVisible="False" Background="Transparent"/> is required [to trigger the Border event handlers] when we set its Background to a non-null value.




    Sunday, August 19, 2012 4:02 PM