The data binding not working in custom ListViewItem style

aluzi liu 486 Reputation points
2023-05-15T16:39:55.03+00:00

I use ListView to display data, and I need fully control the mouse hover, selected visual state of ListViewItem, So I define a custom ListViewItem style:

        <ListView ItemsSource="{x:Bind persons}">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="Background" Value="Transparent" />
                    <Setter Property="TabNavigation" Value="Local" />
                    <Setter Property="Padding" Value="0" />
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                    <Setter Property="UseSystemFocusVisuals" Value="False" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListViewItem">
                                <Grid x:Name="Bd" Background="PaleVioletRed" Margin="10" Padding="4">
                                    <VisualStateManager.VisualStateGroups>
                                        <VisualStateGroup x:Name="CommonStates">
                                            <VisualState x:Name="Normal"/>
                                            <VisualState x:Name="PointerOver">
                                                <VisualState.Setters>
                                                    <Setter Target="Bd.Background" Value="#6f9cf7"/>
                                                </VisualState.Setters>
                                            </VisualState>
                                            <VisualState x:Name="Selected">
                                                <VisualState.Setters>
                                                    <Setter Target="Bd.Background" Value="#335cad"/>
                                                </VisualState.Setters>
                                            </VisualState>
                                            <VisualState x:Name="SelectedPointerOver">
                                                <VisualState.Setters>
                                                    <Setter Target="Bd.Background" Value="#173b85"/>
                                                </VisualState.Setters>
                                            </VisualState>
                                        </VisualStateGroup>
                                    </VisualStateManager.VisualStateGroups>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="auto"/>
                                        <RowDefinition Height="auto"/>
                                        <RowDefinition Height="auto"/>
                                    </Grid.RowDefinitions>
                                    <Image Source="{Binding ImageUrl}" Width="180" Height="180"/>
                                    <TextBlock Grid.Row="1" HorizontalAlignment="Center" Foreground="#000" Text="{Binding Name}"/>
                                    <TextBlock Grid.Row="2" HorizontalAlignment="Center" Foreground="BlueViolet" Text="{Binding Age}"/>
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.ItemContainerStyle>                
        </ListView>

C# code is:

    public class BINPerson
    {
        public string Name { get; set; }
        public double Age { get; set; }
        string imageUrl = "";
        public string ImageUrl
        {
            get
            {
                return imageUrl;
            }
            set => imageUrl = value;
        }
    }

    public sealed partial class ListViewTest : Window
    {
        public ObservableCollection<BINPerson> persons { get; set; }
        public ListViewTest()
        {
            this.InitializeComponent();
            persons = new ObservableCollection<BINPerson> {
                new BINPerson { Name = "Tom", Age = 22, ImageUrl = "https://tse3-mm.cn.bing.net/th/id/OIP-C.QCCHiDia-3rwlugbjE25HwHaE4?w=274&h=180&c=7&r=0&o=5&pid=1.7" },
                    new BINPerson { Name = "Lily", Age = 23, ImageUrl = "https://tse4-mm.cn.bing.net/th/id/OIP-C.r3Tn7N9bculvfp-TSBYSMgHaE8?w=276&h=184&c=7&r=0&o=5&pid=1.7" }
                    };
        }
    }

When I run the application, I can only see 2 blank item, it seems that "{Binding}" command not work at all.

I also try "DataTemplte" like this:

        <ListView ItemsSource="{x:Bind persons}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:BINPerson">
                    <Grid x:Name="Bd" Background="PaleVioletRed" Margin="10" Padding="4">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="auto"/>
                            <RowDefinition Height="auto"/>
                            <RowDefinition Height="auto"/>
                        </Grid.RowDefinitions>
                        <Image Source="{x:Bind ImageUrl}" Width="180" Height="180"/>
                        <TextBlock Grid.Row="1" HorizontalAlignment="Center" Foreground="#000" Text="{x:Bind Name}"/>
                        <TextBlock Grid.Row="2" HorizontalAlignment="Center" Foreground="BlueViolet" Text="{x:Bind Age}"/>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>                
        </ListView>

In this case, data can be display as expected, but I can not modify default mouse hover or selected visual state of ListViewItem, so data template is not my choice.

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,534 questions
Windows App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
739 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Jeanine Zhang-MSFT 9,351 Reputation points Microsoft Vendor
    2023-05-16T06:27:53.4+00:00

    Hello,

    Welcome to Microsoft Q&A!

    According to your description, whether you want to set the background color of the ListViewItem on mouse hover? If so I suggest you could try to modify the value of PointerOverBackground Property.

    You could follow the steps:

    1, Add the Style in the StackPanel.Resources.

    You could find TargetType="ListViewItem" x:Key="ListViewItemRevealStyle" in the generic.xaml. And you could copy it directly into XAML.

            <StackPanel.Resources>
    
                <Style TargetType="ListViewItem" x:Key="testStyle">
                    <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
                    <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
                    <Setter Property="Background" Value="{ThemeResource ListViewItemBackground}" />
                    <Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}" />
                    <Setter Property="TabNavigation" Value="Local" />
                    <Setter Property="IsHoldingEnabled" Value="True" />
                    <Setter Property="Padding" Value="12,0,12,0" />
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                    <Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}" />
                    <Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}" />
                    <Setter Property="AllowDrop" Value="False" />
                    <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
                    <Setter Property="FocusVisualMargin" Value="0" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListViewItem">
                                <ListViewItemPresenter ContentTransitions="{TemplateBinding ContentTransitions}"
                            x:Name="Root"
                            Control.IsTemplateFocusTarget="True"
                            FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
                            SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}"
                            CheckBrush="{ThemeResource ListViewItemCheckBrush}"
                            CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}"
                            DragBackground="{ThemeResource ListViewItemDragBackground}"
                            DragForeground="{ThemeResource ListViewItemDragForeground}"
                            FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}"
                            FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}"
                            PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}"
                            PointerOverBackground="Red"
                            PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}"
                            SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}"
                            SelectedForeground="{ThemeResource ListViewItemForegroundSelected}"
                            SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}"
                            PressedBackground="{ThemeResource ListViewItemBackgroundPressed}"
                            SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}"
                            DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
                            DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
                            ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
                            HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                            VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                            ContentMargin="{TemplateBinding Padding}"
                            CheckMode="{ThemeResource ListViewItemCheckMode}"
                            RevealBackground="{ThemeResource ListViewItemRevealBackground}"
                            RevealBorderThickness="{ThemeResource ListViewItemRevealBorderThemeThickness}"
                            RevealBorderBrush="{ThemeResource ListViewItemRevealBorderBrush}">
    
                                    <VisualStateManager.VisualStateGroups>
                                        <VisualStateGroup x:Name="CommonStates">
                                            <VisualState x:Name="Normal" />
                                            <VisualState x:Name="Selected" />
    
                                            <VisualState x:Name="PointerOver">
                                                <VisualState.Setters>
                                                    <revealBrushPresent:Setter Target="Root.(media:RevealBrush.State)" Value="PointerOver" xmlns:revealBrushPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsTypePresent(Microsoft.UI.Xaml.Media.RevealBrush)" />
                                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}" />
    
                                                </VisualState.Setters>
                                            </VisualState>
    
                                            <VisualState x:Name="PointerOverSelected">
                                                <VisualState.Setters>
                                                    <revealBrushPresent:Setter Target="Root.(media:RevealBrush.State)" Value="PointerOver" xmlns:revealBrushPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsTypePresent(Microsoft.UI.Xaml.Media.RevealBrush)" />
                                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}" />
    
                                                </VisualState.Setters>
                                            </VisualState>
                                            <VisualState x:Name="PointerOverPressed">
                                                <VisualState.Setters>
                                                    <revealBrushPresent:Setter Target="Root.(media:RevealBrush.State)" Value="Pressed" xmlns:revealBrushPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsTypePresent(Microsoft.UI.Xaml.Media.RevealBrush)" />
                                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}" />
    
                                                </VisualState.Setters>
                                            </VisualState>
    
                                            <VisualState x:Name="Pressed">
                                                <VisualState.Setters>
                                                    <revealBrushPresent:Setter Target="Root.(media:RevealBrush.State)" Value="Pressed" xmlns:revealBrushPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsTypePresent(Microsoft.UI.Xaml.Media.RevealBrush)" />
                                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}" />
    
                                                </VisualState.Setters>
                                            </VisualState>
    
                                            <VisualState x:Name="PressedSelected">
                                                <VisualState.Setters>
                                                    <revealBrushPresent:Setter Target="Root.(media:RevealBrush.State)" Value="Pressed" xmlns:revealBrushPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsTypePresent(Microsoft.UI.Xaml.Media.RevealBrush)" />
                                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}" />
    
                                                </VisualState.Setters>
                                            </VisualState>
    
                                        </VisualStateGroup>
    
                                        <VisualStateGroup x:Name="DisabledStates">
                                            <VisualState x:Name="Enabled" />
    
                                            <VisualState x:Name="Disabled">
                                                <VisualState.Setters>
                                                    <Setter Target="Root.RevealBorderThickness" Value="0" />
    
                                                </VisualState.Setters>
                                            </VisualState>
    
                                        </VisualStateGroup>
    
                                    </VisualStateManager.VisualStateGroups>
                                </ListViewItemPresenter>
    
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
    
            </StackPanel.Resources>
    
    

    2, Modify the value of PointerOverBackground Property as you like.

    PointerOverBackground="Red"
    

    3, Add ItemContainerStyle Property to set the Style that is applied to the container element generated for ListView item.

    <ListView ItemsSource="{x:Bind persons}" ItemContainerStyle="{StaticResource testStyle}" >
    

    Result:

    User's image

    Thank you.

    Jeanine


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.