0

I want to change the Background color of my ListViewItems based on the value of the boolean property EstaGuardado of my model class Permiso.

namespace Modelo.Autenticacion
{
    public class Permiso
    {
        public int Id { get; set; }
        public string Nombre { get; set; }
        public bool EstaGuardado { get; set; } = false;
    }
}

The permissions are loaded on page initialization alongside the roles.

When a Rol is selected, the permissions are loaded into the ObservableCollection<Permiso> FilteredPermisos which is used by the PermisosListView:

private void OnRolSeleccionado(object sender, SelectionChangedEventArgs e)
{
    _rolSeleccionado = RolesListView.SelectedItem as Rol;
    if (_rolSeleccionado != null)
    {
        Permisos.Clear();
        FilteredPermisos.Clear();

        foreach (var permiso in _rolSeleccionado.Permisos)
        {
            Permisos.Add(permiso);
            FilteredPermisos.Add(permiso);
        }

        // Update the header text with the selected role name
        PermisosHeaderTextBlock.Text = $"Permisos del rol {_rolSeleccionado.Nombre}";
    }
}

The XAML:

 <Page.Resources>
     <local2:EstaGuardadoToBackgroundConverter x:Key="EstaGuardadoToBackgroundConverter"/>
 </Page.Resources>

  <ListView x:Name="PermisosListView" Grid.Row="1" ItemsSource="{x:Bind FilteredPermisos, Mode=OneWay}">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <ItemsWrapGrid Orientation="Horizontal" MaximumRowsOrColumns="5"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem" BasedOn="{StaticResource ListViewItemRevealStyle}">
                
                <Setter Property="Margin" Value="2"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Background" Value="{Binding EstaGuardado, Converter={StaticResource EstaGuardadoToBackgroundConverter}, Mode=OneWay}"/>
                <Setter Property="MinWidth" Value="150"/>
                <Setter Property="Padding" Value="0"/>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local1:Permiso">
                <StackPanel Orientation="Vertical" Padding="5" Spacing="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Top">
                        <TextBlock Text="{Binding Nombre}" FontWeight="Bold" FontSize="14" Grid.Column="0" VerticalAlignment="Center"/>
                        <Button Content="X" Click="OnEliminarPermisoClick" Tag="{Binding}" Grid.Column="1" Margin="5,0,0,0"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Top" Spacing="5">
                        <TextBlock Text="ID:" Style="{StaticResource FooterTextStyle}"/>
                        <TextBlock Text="{Binding Id}" Style="{StaticResource FooterTextStyle}"/>
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

However, the EstaGuardadoToBackgroundConverter is never called.

I managed to get the Converter called by using it inside the <ListView.ItemTemplate> block instead. However, the background is being set on the StackPanel of my template, not on the base container of the ListViewItem, which leaves gaps on the sides even after setting the padding to zero.

 <ListView.ItemTemplate>
     <DataTemplate x:DataType="local1:Permiso">
         <StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{Binding EstaGuardado, Converter={StaticResource EstaGuardadoToBackgroundConverter}, Mode=OneWay}">

reference

2 Answers 2

0

This might work:

<ListView...>
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local1:Permiso">
            <ListViewItem Background="{x:Bind EstaGuardado, Converter={StaticResource EstaGuardadoToBackgroundConverter}, Mode=OneWay}">
                ...
            </ListViewItem>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
Sign up to request clarification or add additional context in comments.

Comments

0

Modify this to your liking:

Xaml:

<Page
    x:Class="YourProjectName.Views.SimpleListViewTest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:YourProjectName.ViewModels"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Page.Resources>
        <local:BoolToBrushConverter x:Key="BoolToBrush"/>
    </Page.Resources>

    <Grid>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="10">
            <ListView Background="{Binding IsHighlighted, Converter={StaticResource BoolToBrush}}">
                <ListViewItem Content="Item 1"/>
                <ListViewItem Content="Item 2"/>
                <ListViewItem Content="Item 3"/>
            </ListView>

            <Button Content="Toggle Background" Click="ToggleBackground_Click"/>
        </StackPanel>
    </Grid>
</Page>

Code Behind

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using YourProjectName.ViewModels;

namespace YourProjectName.Views
{
    public sealed partial class SimpleListViewTest : Page
    {
        public SimpleListViewTestViewModel ViewModel { get; }

        public SimpleListViewTest()
        {
            this.InitializeComponent();
            ViewModel = new ViewModels.SimpleListViewTestViewModel();
            this.DataContext = ViewModel;
        }

        private void ToggleBackground_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.IsHighlighted = !ViewModel.IsHighlighted;
        }
    }
}

View Model with Converter

using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Media;
using System;
using System.ComponentModel;
using Microsoft.UI;

namespace YourProjectName.ViewModels;

public class SimpleListViewTestViewModel : INotifyPropertyChanged
{
    private bool _isHighlighted;
    public bool IsHighlighted
    {
        get => _isHighlighted;
        set
        {
            _isHighlighted = value;
            OnPropertyChanged(nameof(IsHighlighted));
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class BoolToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value is bool isHighlighted)
        {
            return isHighlighted ? new SolidColorBrush(Colors.LightGreen) : new SolidColorBrush(Colors.LightGray);
        }
        return new SolidColorBrush(Colors.Transparent);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Output:

enter image description here

enter image description here

Also, note that a button is not required. All the button did was change the value of IsHighlighted.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.