ARTICLE

DisablingCombobox Items in Silverlight ComboBox

Posted by Santhosh Kumar Jayaraman Articles | Silverlight with C# February 28, 2012
In this article, we are going to see how to disable items in a Silverlight ComboBox using MVVM.
Reader Level:
Download Files:
 

Introduction

There might be some scenarios in which a user should not be able to select items in a ComboBox. For example, I have year and month ComboBoxes and if I select the current year, I should not be able to select future months for this year. But when I select previous years, I should be able to select any month.

silverlight1.gif

MainPage.xaml:

The Silverlight ComboBoxItem has an IsEnabled property which we can set to true or false based on our requirements. Add the code shown below in the Resources.

<StyleTargetType="ComboBoxItem">
    <Setter Property="IsEnabled" Value="{BindingIsActive}"/>
</Style>

IsActive is a property which I am going to add for the items collection.

Complete XAML code:

<UserControl x:Class="ComboBoxInactiveItems.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
xmlns:vm="clr-namespace:ComboBoxInactiveItems">
    <UserControl.Resources>
        <vm:ViewModel x:Key="ViewModel"/>
        <StyleTargetType="ComboBoxItem">
            <Setter Property="IsEnabled" Value="{BindingIsActive}"/>
            </Style>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White"DataContext="{Binding Source={StaticResourceViewModel}}">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <ComboBox x:Name="cmbYear"SelectionChanged="cmbYear_SelectionChanged"ItemsSource="{Binding Year
"Grid.Row="0"Grid.Column="0" Width="100"HorizontalAlignment="Center"/>
        <ComboBox x:Name="cmbMonth"ItemsSource="{Binding Month
"DisplayMemberPath="MonthName"Grid.Row="0"Grid.Column="1" Width="100"/>
    </Grid>
</
UserControl>

ViewModel

In the ViewModel, I added a ViewModelBase which has a NotifyPropertyChanged event. I added a month class which inherits from ViewModelBase. I have 3 properties inside the Month class.

  1. MonthName(string)
  2. MonthValue(int)
  3. IsActive(bool)

    public class Month : ViewModelBase
    {
        privateboolm_IsActive;
        public Month()
        {
            IsActive = true;
        }
        public string MonthName
        {
            get;
            set;
        }
        public int MonthValue
        {
            get;
            set;
        }
        public bool IsActive
        {
            get;
            {
                returnm_IsActive;
            }
           
set
            {
                m_IsActive = value;
                NotifyPropertyChanged("IsActive");
            }
        }
    }

In the ViewModel class I have a property which is a type of List<Month>.

    public class ViewModel
    {
        private List<Month>m_Month;
        private List<int>m_Year;
        public List<Month> Month
        {
            get;
            {
                if (m_Month == null)
                {
                    m_Month = newList<Month>()
                    {
                        new Month{MonthName="January",MonthValue=1},
                        new Month{MonthName="February",MonthValue=2},
                        new Month{MonthName="March",MonthValue=3},
                        new Month{MonthName="April",MonthValue=4},
                        new Month{MonthName="May",MonthValue=5},
                        new Month{MonthName="June",MonthValue=6},
                        new Month{MonthName="July",MonthValue=7},
                        new Month{MonthName="August",MonthValue=8},
                        new Month{MonthName="September",MonthValue=9},
                        new Month{MonthName="October",MonthValue=10},
                        new Month{MonthName="November",MonthValue=11},
                        new Month{MonthName="December",MonthValue=12}
                    };
                }

                return m_Month;
            }
        }
    }

Complete ViewModel.cs code:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.Generic;

namespace ComboBoxInactiveItems
{
    public class ViewModelBase :
INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
 
    public class
ViewModel
    {
        private List<Month> m_Month;
        private List<int> m_Year;
        public List<Month> Month
        {
           
get
            {
                if (m_Month == null)
                {
                    m_Month = new List<Month>()
                    {
                        new Month{MonthName="January",MonthValue=1},
                        new Month{MonthName="February",MonthValue=2},
                        new Month{MonthName="March",MonthValue=3},
                        new Month{MonthName="April",MonthValue=4},
                        new Month{MonthName="May",MonthValue=5},
                        new Month{MonthName="June",MonthValue=6},
                        new Month{MonthName="July",MonthValue=7},
                        new Month{MonthName="August",MonthValue=8},
                        new Month{MonthName="September",MonthValue=9},
                        new Month{MonthName="October",MonthValue=10},
                        new Month{MonthName="November",MonthValue=11},
                        new Month{MonthName="December",MonthValue=12}
                    };
                }
                return m_Month;
            }
        } 
        public List<int> Year
        {
           
get
            {
                int YearStart = (DateTime.Today.Year) - 5;
                int YearEnd = (DateTime.Today.Year);
                m_Year = new List<int>();
                while (YearStart <= YearEnd)
                {
                    m_Year.Add(YearStart);
                    YearStart = YearStart + 1;
                }
                return m_Year;
            }
        }
    } 
    public class Month :
ViewModelBase
    {
        private bool m_IsActive;
        public Month()
        {
            IsActive = true;
        }
        public string MonthName { get; set; }
        public int MonthValue { get; set; }
        public bool IsActive
        {
           
get
            {
                return m_IsActive;
            }
           
set
            {
                m_IsActive = value;
                NotifyPropertyChanged("IsActive");
            }
        }
    } 
}

How it works:

Now based on the selection of year in the ComboBox, I have to set the IsActive property to true or false, which will enable/disable items in a ComboBox. Remember we have already bound this IsActive property with the IsEnabled property in ComboBoxItemstyle.So in my Year ComboBox selection changed event, I am writing the below code which will enable and disable items.

    private void cmbYear_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
       
//Validating whether user selected current year
        if (Convert.ToInt32(cmbYear.SelectedValue) == DateTime.Today.Year)
        {
            foreach (ComboBoxInactiveItems.Month item incmbMonth.Items)
            {
               
//Finding future months
                if (item.MonthValue>= DateTime.Today.Month)
                {
                   
//Disabling future months by setting IsActive to false
                    item.IsActive = false;
                   
/*Incase if the month has been selected previously but disabled now,
                     * then clearing the selection in the month combobox*/
                    if (item == cmbMonth.SelectedItem)
                    cmbMonth.SelectedIndex = -1;
                }
            }
        }
       
else
        {
           
//Enabling months
            foreach (Month item in ((cmbMonth.Items)))
            {
                item.IsActive = true;
            }  
        }  
    }


You can also set the IsActive property in ViewModel; it depends on your need. You can modify the above code for your application and can disable ComboBox items. I have attached source code also.

Please rate the document and share with your friend if you found it as useful.

Login to add your contents and source code to this article
post comment
     

Hi, Santhosh it's a great effort to accomplish such kind of task keep it up. Thanks for sharing........

Posted by Amit Maheshwari Feb 28, 2012

Really this article is so good.

Posted by Arjun Panwar Feb 28, 2012

Hi Santhosh. Its a nicely presented article. I will surely try this.

Posted by Daisy Krause Feb 28, 2012

Nice representation Santhosh,Thanks for sharing.

Posted by Manish Singh Feb 28, 2012
COMMENT USING
PREMIUM SPONSORS
Over-C is a holistic consortium of communications and technology specialists. We build, deploy and market both business as well as consumer products and solutions.
Join a Chapter
SPONSORED BY
  • PDF reports have never been easier to create. With our included WYSIWYG Designer, you can layout your reports, set up your data source and let DynamicPDF ReportWriter do the rest.
Join a Chapter