Highlight Parent Nodes inside a ListBox using IValueConvertor

Niladri.Biswas
Posted by in WPF category on for Beginner level | Points: 250 | Views : 2307 red flag
Rating: 3 out of 5  
 1 vote(s)

In this article we will look into the implementation of IValue convertor in WPF where by using this we will highlight the Parent node inside a ListBox


 Download source code for Highlight Parent Nodes inside a ListBox using IValueConvertor

Introduction

In this article we will look into the implementation of IValue convertor in WPF where by using this we will highlight the Parent node inside a ListBox.Say we have a collection as under

	India
		-Karnataka
		-Delhi
		-TamilNadu
		-Kerala
		
	Bangaladesh
		-Barishal
		-Chittagong
		-Dhaka
		-Khulna
	
	USA
		-Alabama
		-Alaska
		-New Jersey
		-Oklahoma
	
	Canada
		-Toronto
		-Montreal
		-Edmonton
		-Vancouver

The output we are looking out should be as under

Since this article assumes that the user already has knowledge on IValue convertor, anyway, if someone need to know about it , they may refer to this article in WPF.

Straight to program

First of all , let us create a "CountryStateList" Entity as under

public class CountryStateList
{
	public string Country_State_Id { get; set; }       
	public string Country_State_Name { get; set; }
}

Next, populate the entity with some value

public class DataSource
{
	public ObservableCollection<CountryStateList> GetStateCountryData()
	{
		var countryCollection = new ObservableCollection<CountryStateList>();

		countryCollection.Add(new CountryStateList { Country_State_Id = "C1", Country_State_Name = "India" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S1", Country_State_Name = "  -Karnataka" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S2", Country_State_Name = "  -Delhi" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S3", Country_State_Name = "  -TamilNadu" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S4", Country_State_Name = "  -Kerala" });

		countryCollection.Add(new CountryStateList { Country_State_Id = "C2", Country_State_Name = "Bangaladesh" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S1", Country_State_Name = "  -Barishal" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S2", Country_State_Name = "  -Chittagong" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S3", Country_State_Name = "  -Dhaka" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S4", Country_State_Name = "  -Khulna" });

		countryCollection.Add(new CountryStateList { Country_State_Id = "C3", Country_State_Name = "USA" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S1", Country_State_Name = "  -Alabama" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S2", Country_State_Name = "  -Alaska" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S3", Country_State_Name = "  -New Jersey" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S4", Country_State_Name = "  -Oklahoma" });


		countryCollection.Add(new CountryStateList { Country_State_Id = "C4", Country_State_Name = "Canada" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S1", Country_State_Name = "  -Toronto" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S2", Country_State_Name = "  -Montreal" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S3", Country_State_Name = "  -Edmonton" });
		countryCollection.Add(new CountryStateList { Country_State_Id = "S4", Country_State_Name = "  -Vancouver" });

		return countryCollection;

	}
}

The next step is to create a ViewModel, that will act as the data source for the view

public class StateCountryViewModel : INotifyPropertyChanged
    {
        DataSource _objDataSource = new DataSource();

        private ObservableCollection<CountryStateList> _countrystatelist = new ObservableCollection<CountryStateList>();

        public void LoadMultipleCountryList()
        {
            _countrystatelist = new ObservableCollection<CountryStateList>(_objDataSource.GetStateCountryData());

        }

        public ObservableCollection<CountryStateList> CountryStateList
        {
            get
            {
                return _countrystatelist;
            }
        }

        #region General Propertychange methods
        
        protected void OnPropertyChanged(string PropertyName)
        {
            VerifyPropertyName(PropertyName);

            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
       
        [Conditional("DEBUG")]
        [DebuggerStepThrough]
        private void VerifyPropertyName(string propertyName)
        {
            // Verify that the property name matches a real,  
            // public, instance property on this object.
            if (TypeDescriptor.GetProperties(this)[propertyName] == null)
            {
                string msg = "Invalid property name: " + propertyName;
                throw new Exception(msg);
            }
        }

        #endregion


        public event PropertyChangedEventHandler PropertyChanged;
    }

We have defined a Observable property by the name CountryStateList, that holds the data which the view needs to bind

Next let us create the Xaml for the view

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="600" Width="600"       
         Loaded="Window_Loaded"
        xmlns:local="clr-namespace:WpfApplication1.Converters"
        >
    <Window.Resources>
        <local:HighlightRootElements x:Key="colorrootnode"/>
    </Window.Resources>
    
    <Grid>
        
        <ListBox 
                Name="lstStateCountryType" Width="400" 
                HorizontalAlignment="Stretch" Margin="5" 
                MinHeight="200"  SelectionMode="Extended" 
                MaxHeight="400"  
                IsSynchronizedWithCurrentItem="True"
                ItemsSource="{Binding CountryStateList}" 
               >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Country_State_Name}"
                               Background="{Binding Converter={StaticResource colorrootnode}}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        
    </Grid>
</Window>

We are binding the "Country_State_Name" property to the ListBox as this is the one that we will display.The convertor logic is being defined in "HighlightRootElements.cs" file

public class HighlightRootElements : IValueConverter
{
	#region IValueConverter Members

	public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
	{
		SolidColorBrush _scb = new SolidColorBrush();

		var _countryId = ((CountryStateList)value).Country_State_Id; //Root Index Value

		switch (_countryId)
		{
			case "C1": _scb = Brushes.DarkGoldenrod; break;
			case "C2": _scb = Brushes.Tomato; break;
			case "C3": _scb = Brushes.MidnightBlue; break;
			case "C4": _scb = Brushes.Violet; break;
		}
		return _scb;
	}

	public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
	{
		// throw new NotImplementedException();

		return null;
	}

	#endregion
}

Here in the "Convert" function, we are first capturing the value of the "Country_State_Id" property and then based on the value supplied, we are returning the colors.

Obviously, we need to set the data context for the View and the "MainWindow.Xaml.cs" file looks as under

public partial class MainWindow : Window
{
	public StateCountryViewModel _objViewModel;

	public MainWindow()
	{
		InitializeComponent();
	}

	private void Window_Loaded(object sender, RoutedEventArgs e)
	{
		_objViewModel = new StateCountryViewModel();
		this.DataContext = _objViewModel;
		_objViewModel.LoadMultipleCountryList();
	 
	}        
}

Conclusion

This article is written to give an idea of working with IValue convertor.Hope this will be useful.Experiment code is attached herewith.Thanks for reading

Page copy protected against web site content infringement by Copyscape

About the Author

Niladri.Biswas
Full Name: Niladri Biswas
Member Level: Platinum
Member Status: Member
Member Since: 10/25/2010 11:04:24 AM
Country: India
Best Regards, Niladri Biswas
http://www.dotnetfunda.com
Technical Lead at HCL Technologies

Login to vote for this post.

Comments or Responses

Posted by: Kundan64 on: 1/18/2013 | Points: 25
Very nice article.

Login to post response

Comment using Facebook(Author doesn't get notification)