Monday, 5 August 2013

WPF - Custom ComboBox



In WPF we are going to see a Combo Box with custom template ,Which have a checkbox in it.To have a CheckBox in Combo we have to define the item template.

This example consists of a  Select the value and retrieve the value selected in combobox and display in textbox.





Example consists of days are the item of combobox.

<window height="177" title="TestWindow" width="378" x:class="sample_wpf.MainWindow" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <stackpanel>
        <combobox height="30" margin="10,10,10,10" name="customcombo" selectionchanged="customcombo_SelectionChanged" width="116">
        <combobox .itemtemplate="">
            <datatemplate>
                <stackpanel orientation="Horizontal">
                    <checkbox checked="CheckBox_Checked" content="{Binding Data}" ischecked="{Binding IsSelected,Mode=TwoWay}" margin="0,2,3,2" unchecked="CheckBox_Unchecked"></checkbox>                
                </stackpanel>
            </datatemplate>
        </combobox>
    </combobox>
        <button click="Button_Click" width="117">Get Selected value</button>
        <textblock height="30" margin="20,20,20,20" name="val"></textblock>
    </stackpanel>
</window>



Now when we select the values in combobox, we have to ensure that for select all  options all items in combobox should be selected.

public partial class MainWindow : Window
    {
        DaysCollection dc = new DaysCollection();
        public MainWindow()
        {
            InitializeComponent();          
            dc.Add(new ComboTemplate<string>(false, "Select All"));
            dc.Add(new ComboTemplate<string>(false, "Sunday"));
            dc.Add(new ComboTemplate<string>(false, "Monday"));
            dc.Add(new ComboTemplate<string>(false, "Tuesday"));
            dc.Add(new ComboTemplate<string>(true, "Wednesday"));
            dc.Add(new ComboTemplate<string>(false, "Thursday"));
            dc.Add(new ComboTemplate<string>(false, "Friday"));
            dc.Add(new ComboTemplate<string>(false, "Saturday"));
            customcombo.ItemsSource = dc;
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            CheckBox _selectall = sender as CheckBox;
            if(_selectall.IsChecked.HasValue)
            if (_selectall.IsChecked.Value && _selectall.Content == "Select All")
            {
                foreach (ComboTemplate<string> _val in dc)
                {
                    _val.IsSelected = true;
                }
            }
        }

        private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            CheckBox _selectall = sender as CheckBox;
            if (_selectall.IsChecked.HasValue)
                if (!_selectall.IsChecked.Value && _selectall.Content == "Select All")
                {
                    foreach (ComboTemplate<string> _val in dc)
                    {
                        _val.IsSelected = false;
                    }
                }
        }

        private void customcombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            val.Text = "";
            List<string> daysselected = new List<string>();
            foreach (ComboTemplate<string> _selected in customcombo.ItemsSource)
            {
                if (_selected.IsSelected)
                {
                    if (_selected.Data != "Select All")
                        val.Text += _selected.Data+", ";
                }
            }
            if (val.Text.Length > 0)
            {
                val.Text = val.Text.Substring(0, val.Text.Length - 2);
            }
        }
      
    }

    class DaysCollection : ObservableCollection<ComboTemplate<string>>
    {

    }

    class ComboTemplate<T> : INotifyPropertyChanged
    {
        private bool _IsSelected;
       
        public bool IsSelected
        {
            set
            {
                if (IsSelected != value)
                {
                    _IsSelected = value;
                    OnPropertyChange("IsSelected");
                }
            }
            get
            {
                return _IsSelected;
            }
        }

        public T Data { set; get; }

        public ComboTemplate(T data)
        {
            Data = data;
        }

        public ComboTemplate(bool isSelected,T data)
        {
            _IsSelected = isSelected;
            Data = data;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChange(string propertyname)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyname));
            }
        }
    }





From the above image you can see the values selected in combobox in a Textblock.