Search code examples
c#wpfdata-bindingcomboboxselectedindex

Binding the SelectedIndex (Combobox) are not working from codebehind file


I have a window with a combobox. This comboboxhas 5 ComboboxItems.

I binding the SelectedItem (combobox) to the ComboBoxSelectedIndex Property in my code behind file.

In the example I want that it is not possible to select the items 4 and 5.

But i can select the item 4 and 5. What's wrong?

xaml code:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStartupLocation="CenterScreen"
        Height="350"
        Width="500">
    <StackPanel VerticalAlignment="Center">
        <ComboBox SelectedIndex="{Binding Path=ComboBoxSelectedIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
            <ComboBoxItem>Item 1</ComboBoxItem>
            <ComboBoxItem>Item 2</ComboBoxItem>
            <ComboBoxItem>Item 3</ComboBoxItem>
            <ComboBoxItem>Item 4</ComboBoxItem>
            <ComboBoxItem>Item 5</ComboBoxItem>
        </ComboBox>     
    </StackPanel>
</Window>

codebehind file:

namespace WpfApplication1
{
    public partial class MainWindow : INotifyPropertyChanged
    {
        private int _selectedIndex;

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        public int ComboBoxSelectedIndex
        {
            get { return _selectedIndex; }
            set
            {
                if (value < 3)
                {
                    _selectedIndex = value;
                }
                OnPropertyChanged("ComboBoxSelectedIndex");
                Trace.WriteLine(ComboBoxSelectedIndex);
            }
        }

        #region Implementation of INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
    }
}

(I am aware that I can solve this problem with the property Is Enabled. But I don't what that here)


Solution

  • Create your custom combobox to implement this

    <StackPanel Orientation="Vertical">
        <wpfProj:ExtendedCombobBox 
           SelectedIndex="{Binding Path=ComboBoxSelectedIndex, 
                                  Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
           MaxSelectedIndex="{Binding Path=MaxSelectedIndex}">
            <ComboBoxItem>Item 1</ComboBoxItem>
            <ComboBoxItem>Item 2</ComboBoxItem>
            <ComboBoxItem>Item 3</ComboBoxItem>
            <ComboBoxItem>Item 4</ComboBoxItem>
            <ComboBoxItem>Item 5</ComboBoxItem>
        </wpfProj:ExtendedCombobBox>
    </StackPanel>
    

    And code the custom combobox

    public class ExtendedCombobBox:ComboBox
    {
        public static readonly DependencyProperty MaxSelectedIndexProperty =
            DependencyProperty.Register("MaxSelectedIndex", typeof (int), typeof (ExtendedCombobBox), new PropertyMetadata(default(int)));
    
        public int MaxSelectedIndex
        {
            get { return (int) GetValue(MaxSelectedIndexProperty); }
            set { SetValue(MaxSelectedIndexProperty, value); }
        }
    
        protected override void OnSelectionChanged(SelectionChangedEventArgs e)
        {
            if (Items.IndexOf(e.AddedItems[0]) > MaxSelectedIndex)
                e.Handled = true;
            else
                base.OnSelectionChanged(e);
        }
    }
    

    UPD1. Or you can just use standard one and subscribe to the SelectionChanged event. But I'd prefer to use custombobox.