Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

How do you conditionally format the items in a WPF Listbox

Posted on 2011-03-20
6
Medium Priority
?
2,213 Views
Last Modified: 2013-11-12
Hi

I am starting to learn WPF and want to know how can you format the items in a Listbox conditionally based on content.  For instance, I have a procedure that adds items to the listbox.  Each item added will contain somewhere in the string either the substring Male or Female.  How can I dynamically change the font and the background of the listbox item based on the text string's contents?

Thanks
0
Comment
Question by:Vyyk_Drago
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 4

Expert Comment

by:grishav
ID: 35174511
Hi,
You can do it with DataTriggers in xaml.
You need to define a property in your code - say, named Gender (in its getter you can return your substring, for example)
Then in XAML you can write something like this:


<ListBox ....> 
	<ListBox.ItemContainerStyle> 
		<Style TargetType="{x:Type ListBoxItem}">
			<Style.Triggers>
				<DataTrigger Binding="{Binding Path=Gender}" Value="Male">
					<Setter Property="Background" Value="Red" />
				</DataTrigger>
				<DataTrigger Binding="{Binding Path=Gender}" Value="Female">
					<Setter Property="Background" Value="Green" />
				</DataTrigger>
			</Style.Triggers>
		</Style>
	</ListBox.ItemContainerStyle> 
</ListBox>

Open in new window

0
 

Author Comment

by:Vyyk_Drago
ID: 35175190
Hi grishav

Thanks - just one question since I am totally a n00b and also still vinding my way in VB .NET - after adding the XAML code as you suggest, where do I define the Gender property?  I suppose this property has to be related to my ListBox somehow?

Thanks
Vyyk
0
 
LVL 4

Expert Comment

by:grishav
ID: 35175264
I suppose that each item in your list box is instance of some class which you defined in a code-behind.
If it is so, than you need to add the property to that class.
If not, probably you should post the code where you give the content to your listbox.
How do you define what to show in it?
Is it
<ListBox ItemsSource=some_collection_of_your_objects ... ?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Vyyk_Drago
ID: 35175507
Hi

The class looks like this:

Public Class RecitalReaderWriter

    Public ReadOnly Property Recital(ByVal strPerformancePath As String) As Collection
        Get
            Dim srPerformanceReader As System.IO.StreamReader
            Dim colRecitalLines As New Collection

            srPerformanceReader = File.OpenText(strPerformancePath)

            While srPerformanceReader.Peek <> -1
                colRecitalLines.Add(srPerformanceReader.ReadLine())
            End While

            Return colRecitalLines
        End Get
    End Property

Open in new window


The Property is called like this:

 
Private Sub btnOpenPerformance_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnOpenPerformance.Click

        Dim ofdlg As New Microsoft.Win32.OpenFileDialog

        With ofdlg
            .Multiselect = False
            .DefaultExt = ".txt"
            .Filter = "Text Documents (.txt)|*.txt"
            If .ShowDialog = True Then
                colRecitalLines = rctlrdwr.Recital(.FileName)
                lbPerformance.ItemsSource = colRecitalLines
            End If
        End With

    End Sub

Open in new window


I have added the xaml below to my Listbox definition:

 
<ListBox Name="lbPerformance">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="{x:Type ListBoxItem}">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=Recital}" Value="female">
                                <Setter Property="Background" Value="Orange" />
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Path=Recital}" Value="male">
                                <Setter Property="Background" Value="Green" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                 </ListBox.ItemContainerStyle>
            </ListBox>

Open in new window


However, even though the items are added successfully added to the lisbow, the formatting is not applied to relevant items.  I cannot figure out what I am doing wrong :(

Thanks
V
0
 
LVL 4

Accepted Solution

by:
grishav earned 2000 total points
ID: 35175594
I think you need to understand more how data binding works in WPF.
Here is good page to start with:
http://msdn.microsoft.com/en-us/library/ms750612.aspx

Basically, you read from file one line at a time and add each string you get to the collection "as is".
Instead, you must define some data class (called RecitalLine, for example).
In this class you can also define properties (such as Gender).
You can also override toString method if all you want in ListBox is a textual representation  of RecitalLine.
Than you will define new instance for this class based on each line you read from the file.
Than you'll add all instances of  RecitalLine (and not the plain strings) to the collection.
Now, in ItemContainerStyle in Xaml you need to style each item according to properties of this specific item - for example, Gender. So you need to write {Binding Path=Gender}. Not {Binding Path=Recital}
(unless, of course, you will define property named Recital in each RecitalLine - which is not what you meant I think)

It is hard to understand what code to write, when you don't understand what is bound to what.
I really recommend that you start with the article I mentioned in the beginning (or just google for 'WPF data binding') - before you write the code.
Good luck.
0
 

Author Closing Comment

by:Vyyk_Drago
ID: 35176167
Thanks for the awesome help!  Never could have worked this out without your help!
0

Featured Post

NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…

660 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question