WPF: Listview with IValueConverter

This next example is a rather involved look at designing a ListView and using IValueConverter to show if a customer is still having its warranty on the product the customer has purchased.

After converting the warranty info to either Y or N, it will be a lot more easier for the service personal to serve the customers.

MainWindow.xaml
<Window x:Class="ListViewSpace.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ListViewSpace"
        Title="MainWindow"
        Height="350" 
        Width="620" 
        Loaded="OnLoad">
    <Window.Resources>
        <!--ListView Styling Start-->
        <LinearGradientBrush x:Key="BackgroundBrush" StartPoint="0,0" EndPoint="0,1">
            <LinearGradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#FF6FBDE8" Offset="0"/>
                    <GradientStop Color="#FF4385BE" Offset="1"/>
                </GradientStopCollection>
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="HighlightBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
            <LinearGradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#FF97d3f3" Offset="0"/>
                    <GradientStop Color="#FF4385BE" Offset="1"/>
                </GradientStopCollection>
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="BorderBrush" StartPoint="0,0" EndPoint="0,1">
            <LinearGradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#FFAFDDF6" Offset="0"/>
                    <GradientStop Color="#FF2969AA" Offset="1"/>
                </GradientStopCollection>
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="PressedBorderBrush" StartPoint="0,0" EndPoint="0,1">
            <LinearGradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#FF75aac7" Offset="0"/>
                    <GradientStop Color="#FF143c65" Offset="1"/>
                </GradientStopCollection>
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>

        <Style x:Key="GridViewColumnHeaderGripper" TargetType="Thumb">
            <Setter Property="Width" Value="20"/>
            <Setter Property="Background" Value="#2e566b"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Thumb}">
                        <Border Padding="{TemplateBinding Padding}" Background="Transparent">
                            <Rectangle HorizontalAlignment="Center" Width="1" Fill="{TemplateBinding Background}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="{x:Type GridViewColumnHeader}" TargetType="GridViewColumnHeader">
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Foreground" Value="#FFFFFF" />
            <Setter Property="FontWeight" Value="DemiBold"/>

            <Setter Property="MinWidth" Value="40"/>
            <Setter Property="Height" Value="21"/>

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="GridViewColumnHeader">
                        <Grid>
                            <Border Name="HeaderBorder" Padding="{TemplateBinding Padding}" BorderThickness="0,1,0,1" BorderBrush="{StaticResource BorderBrush}" Background="{StaticResource BackgroundBrush}">
                                <ContentPresenter Name="HeaderContent" Margin="0,0,0,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            </Border>
                            <Thumb x:Name="PART_HeaderGripper" HorizontalAlignment="Right" Margin="0,0,-9,0" Style="{StaticResource GridViewColumnHeaderGripper}"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter TargetName="HeaderBorder" Property="Background" Value="{StaticResource HighlightBackgroundBrush}"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="true">
                                <Setter TargetName="HeaderBorder" Property="Background" Value="{StaticResource PressedBorderBrush}"/>
                                <Setter TargetName="HeaderContent" Property="Margin" Value="1,1,0,0"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="Role" Value="Floating">
                    <Setter Property="Opacity" Value="0.7"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="GridViewColumnHeader">
                                <Canvas Name="PART_FloatingHeaderCanvas">
                                    <Rectangle Fill="#60000000" Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}"/>
                                </Canvas>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>
                <Trigger Property="Role" Value="Padding">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="GridViewColumnHeader">
                                <Border Name="HeaderBorder" BorderThickness="0,1,0,1" BorderBrush="{StaticResource BorderBrush}" Background="{StaticResource BackgroundBrush}"/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>

        <Style TargetType="ListViewItem">
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="FontSize" Value="12" />
            <Setter Property="Height" Value="18" />
            <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
        </Style>

        <Style x:Key="BorderedItem" TargetType="ListViewItem">
            <Setter Property="BorderBrush" Value="Red" />
            <Setter Property="BorderThickness" Value="2" />
        </Style>

        <!--ListView Styling End-->
    </Window.Resources>
    <Grid>
        <ListView Name="ListSales" Grid.Row="4" Grid.ColumnSpan="3" 
                  ScrollViewer.VerticalScrollBarVisibility="Auto" 
                  Height="300" 
                  Width="580"
                  ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                  SelectionMode="Multiple"
                  Margin="0,6,6,0"
                  VerticalAlignment="Top">

            <ListView.Resources>
                <local:WarrantyConverter x:Key="boolConverter"/>
            </ListView.Resources>

            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Order Numner" DisplayMemberBinding="{Binding OrderNumber}" Width="100"/>
                    <GridViewColumn Header="Order Date" DisplayMemberBinding="{Binding OrderDate,StringFormat=MMM dd yyyy}" Width="100"/>
                    <GridViewColumn Header="Customer Name" DisplayMemberBinding="{Binding CustomerName}" Width="100"/>
                    <GridViewColumn Header="Address" DisplayMemberBinding="{Binding Address}" Width="190"/>
                    <GridViewColumn Header="Warranty" DisplayMemberBinding="{Binding Warranty,Converter={StaticResource boolConverter}}" Width="100"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace ListViewSpace
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
        }

        private void OnLoad(object sender, RoutedEventArgs e)
        {
            ListSales.ItemsSource = GetSalesData();
        }

        private List<SalesData> GetSalesData()
        {
            List<SalesData> listData = new List<SalesData>();

            try
            {
                Random rnd = new Random();

                String[] states = { "Texas", "California", "Ohio", "Nebraska", "New Jersey" };
                String[] names = { "Janet", "Alison", "Michael", "Dave", "Molly", "Eileen", "Samuel", "John", "Rose", "Carol", "Peter", "April", "Steven", "Bryan", "Doreen" };
                Boolean[] warr = { false, true, false, true, false, true, true, false };

                SalesData[] salesdata = new SalesData[10];

                for (int index = 0; index < salesdata.Length; index++)
                {
                    salesdata[index] = new SalesData();
                    salesdata[index].Address = String.Format("No.  {0}, {1} ", rnd.Next(1, 1000), states[rnd.Next(0, states.Length - 1)].ToString());
                    salesdata[index].CustomerName = names[rnd.Next(0, 14)].ToString();
                    salesdata[index].OrderDate = DateTime.Now.AddDays(rnd.Next(1, 30));
                    salesdata[index].OrderNumber = rnd.Next(1, 1000);
                    salesdata[index].Warranty = warr[rnd.Next(0, warr.Length - 1)];

                    listData.Add(salesdata[index]);
                }
            }
            catch (Exception)
            {
                throw;
            }
            return listData;
        }
    }

    internal class SalesData
    {
        public SalesData()
        { }

        public int OrderNumber { get; set; }
        public DateTime OrderDate { get; set; }
        public String CustomerName { get; set; }
        public String Address { get; set; }
        public Boolean Warranty { get; set; }
    }

    public class WarrantyConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            String val = String.Empty;

            if ((Boolean) value == true)
            {
                val = "Y";
                return val;
            }
            else
            {
                val = "N";
                return val;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Boolean val = false;

            if ((String) value == "Y")
            {
                val = true;
                return val;
            }
            else
            {
                val = false;
                return val;
            }
        }
    }
}

listview

If you just remove Converter={StaticResource boolConverter} in line 153 in MainWindow.xaml, the output will be as below:

listview1

 

Series Navigation<< WPF: Date conversion with IValueConverter
WPF: Master-detail view >>