Home > Enterprise >  WPF ListViewItem - Switch focusable and IsMouseOver background values
WPF ListViewItem - Switch focusable and IsMouseOver background values

Time:03-04

I am trying to display a list with different object types (in the example dogs and cats). The types should be visually different (in the example realized by red and blue font in the DataTemplate in MainWindow.xaml).

Additionally I want that cats can neither be selected, nor that they get a colored background at the IsMouseOver trigger. However, I am not succeeding in the latter. I have left a few of my attempts as comments in MainWindow.xaml.

MainWindow.xaml

<Window.Resources>
    <local:AnimalToFocusConverter x:Key="AnimalToFocusConverter" />
    <local:AnimalToBackgroundColorConverter x:Key="AnimalToBackgroundColorConverter" />

    <DataTemplate DataType="{x:Type local:Dog}">
        <TextBlock Text="{Binding Path=Name}" Foreground="Red" />
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:Cat}">
        <TextBlock Text="{Binding Path=Name}" Foreground="Blue" />
    </DataTemplate>
</Window.Resources>
<Grid>
    <ListView ItemsSource="{Binding AnimalCollection}">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="Background" Value="Transparent" />
                <!--<Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListViewItem}">
                            <Grid Background="Transparent">
                                <ContentPresenter />
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="{Binding Converter={StaticResource AnimalToBackgroundColorConverter}}" />
                    </Trigger>
                </Style.Triggers>-->
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>
</Grid>

Animals.cs

public class Animals
{
    public ObservableCollection<IAnimal> AnimalCollection { get; set; } = new ObservableCollection<IAnimal>();

    public Animals()
    {
        AnimalCollection.Add(new Dog());
        AnimalCollection.Add(new Dog());
        AnimalCollection.Add(new Cat());
        AnimalCollection.Add(new Dog());
        AnimalCollection.Add(new Cat());
    }
}

IAnimal.cs

public interface IAnimal
{
}

Dog.cs / Cat.cs

public class Dog : ObservableObject, IAnimal
{
    private static int counter = 0;
    public string Name { get; set; }

    public Dog()
    {
        Name = $"Dog{  counter}";
    }
}

Converter.cs

[ValueConversion(typeof(IAnimal), typeof(bool))]
public class AnimalToFocusConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value switch
        {
            Dog => true,
            Cat => false,
            _ => false,
        };
    }

// ...

[ValueConversion(typeof(IAnimal), typeof(SolidColorBrush))]
public class AnimalToBackgroundColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value switch
        {
            Dog => new SolidColorBrush(Colors.LightBlue),
            Cat => new SolidColorBrush(Colors.Transparent),
            _ => new SolidColorBrush(Colors.LightBlue),
        };
    }

CodePudding user response:

You could set the IsHitTestVisible property of the ListViewItem containers for the Cat objects to false:

<ListView ItemsSource="{Binding AnimalCollection}">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="IsHitTestVisible"
                    Value="{Binding Converter={StaticResource AnimalToFocusConverter}}" />
        </Style>
    </ListView.ItemContainerStyle>
</ListView>
  • Related