Posted by: Zeeshan Amjad | March 18, 2010

## Creating Bar Graph with List Box

We just saw how to use canvas in the list box to display items wherever we want here. Now we are going to use this and create a bar graph using list box. We are using rectangle to display the bar graph and height of the rectangle is depend on the data. Here is a piece of XAML code to draw rectangle like this.

```  1: <ListBox.ItemTemplate>

2: 	<DataTemplate>

3: 		<Rectangle Width="15" Height="{Binding Value}" Fill="{Binding Name}"/>

4: 	</DataTemplate>

5: </ListBox.ItemTemplate>

6:
In this way we can set the height of the rectangle. We fixed the width and bottom position of the rectangle. The missing piece is set the x position of the rectangle. To do this we define the counter variable in the data set and use that counter variable to set the x position of the rectangle. Here is our data class.
1: public class DataPoint

2: {

3:     public DataPoint(String name, Double counter,  Double value)

4:     {

5:         Name = name;

6:         Counter = counter;

7:         Value = value;

8:     }

9:

10:     public String Name

11:     { get; set; }

12:

13:     public Double Counter

14:     { get; set; }

15:

16:     public Double Value

17:     { get; set; }

18: }

19:
Now we are going to create list of DataPoint and set this list to the items source property of the list box. But there is one small problem in this solution. If we set the value of counter variable 1, 2, 3, and so on then all the rectangles will overlap each other. The other solution is to input the exact value of x coordinate when creating the object of DataPont, such as 10, 20, 30 etc. But this will be over burden.
We can solve this problem by introducing one value converter. The value converter will simply return the x position depending on our algorithm. Just for simplicity we simply return the x position by multiplying the counter by 20. Here is our value converter class.
1: public class CounterConverter : IValueConverter

2: {

3:     public object Convert(object value, Type targetType,

4:         object parameter, CultureInfo cultureInfo)

5:     {

6:         double counter = (double)value;

7:

8:         return counter * 20;

9:     }

10:

11:     public object ConvertBack(object value, Type targetType,

12:         object parameter, CultureInfo cultureInfo)

13:     {

14:         throw new NotImplementedException();

15:     }

16: }

17:
Now we will use this converter class when binding the x value of the rectangle. Here is a piece of XAML code to do this.
1: <local:CounterConverter x:Key="counterConverterObj"/>

2: <Style x:Key="myStyle" TargetType="ListBoxItem">

3: 	<Setter Property="Canvas.Left"

4: 		Value="{Binding Path=Counter,

5: 		Converter={StaticResource counterConverterObj}}"/>

6: 	<Setter Property="Canvas.Bottom" Value="50"/>

7: </Style>

8:
Here is complete XAML code of the program.
1: <Window x:Class="WpfCanvas.Window1"

2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

4:     xmlns:local="clr-namespace:WpfCanvas"

5:     Title="Canvas" Height="300" Width="300">

6:     <Window.Resources>

7:         <local:CounterConverter x:Key="counterConverterObj"/>

8:         <Style x:Key="myStyle" TargetType="ListBoxItem">

9:             <Setter Property="Canvas.Left"

10:                     Value="{Binding Path=Counter,

11:                     Converter={StaticResource counterConverterObj}}"/>

12:             <Setter Property="Canvas.Bottom" Value="50"/>

13:         </Style>

14:     </Window.Resources>

15:     <Grid>

16:         <ListBox Name="list" Margin="5" ItemContainerStyle="{StaticResource myStyle}">

17:             <ListBox.ItemsPanel>

18:                 <ItemsPanelTemplate>

19:                     <Canvas/>

20:                 </ItemsPanelTemplate>

21:             </ListBox.ItemsPanel>

22:             <ListBox.ItemTemplate>

23:                 <DataTemplate>

24:                     <Rectangle Width="15" Height="{Binding Value}" Fill="{Binding Name}"/>

25:                 </DataTemplate>

26:             </ListBox.ItemTemplate>

27:         </ListBox>

28:     </Grid>

29: </Window>

30:
And here is complete C# code of the program.
1: using System;

2: using System.Collections.Generic;

3: using System.Linq;

4: using System.Text;

5: using System.Windows;

6: using System.Windows.Controls;

7: using System.Windows.Data;

8: using System.Windows.Documents;

9: using System.Windows.Input;

10: using System.Windows.Media;

11: using System.Windows.Media.Imaging;

13: using System.Windows.Shapes;

14: using System.Globalization;

15:

16: namespace WpfCanvas

17: {

18:     /// <summary>

19:     /// Interaction logic for Window1.xaml

20:     /// </summary>

21:     public partial class Window1 : Window

22:     {

23:         public Window1()

24:         {

25:             InitializeComponent();

26:

27:             List<DataPoint> test = new List<DataPoint>();

28:

39:

40:             list.ItemsSource = test;

41:         }

42:     }

43:

44:     public class CounterConverter : IValueConverter

45:     {

46:         public object Convert(object value, Type targetType,

47:             object parameter, CultureInfo cultureInfo)

48:         {

49:             double counter = (double)value;

50:

51:             return counter * 20;

52:         }

53:

54:         public object ConvertBack(object value, Type targetType,

55:             object parameter, CultureInfo cultureInfo)

56:         {

57:             throw new NotImplementedException();

58:         }

59:     }

60:

61:     public class DataPoint

62:     {

63:         public DataPoint(String name, Double counter,  Double value)

64:         {

65:             Name = name;

66:             Counter = counter;

67:             Value = value;

68:         }

69:

70:         public String Name

71:         { get; set; }

72:

73:         public Double Counter

74:         { get; set; }

75:

76:         public Double Value

77:         { get; set; }

78:     }

79: }

80:
Here is the output of the program.

__ATA.cmd.push(function() {
__ATA.initVideoSlot('atatags-370373-5f7590aeefcda', {
sectionId: '370373',
});
});

__ATA.cmd.push(function() {
__ATA.initDynamicSlot({
location: 120,
formFactor: '001',
label: {
},
creative: {
},
privacySettings: {
text: 'Privacy settings',
}
}
});
});