DisablingCombobox Items in Silverlight ComboBox


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.


Similar Articles