Search code examples
wpfmvvmdatagridviewcomboboxwpfdatagrid

Remove already selected value from a combobox in datagridview


I have a wpf datagridview and and combobox in the template column. I do not want to show the values already selected for other rows, but in doing this the item that is currently selected also gets removed.

The model is as follows

public class MetadataConfigurationModel : ViewModelBase
{        
    private ObservableCollection<MetadataConfiguration> _metadataConfiguration = new ObservableCollection<MetadataConfiguration>();
    public ObservableCollection<MetadataConfiguration> MetadataConfig
    {
        get { return _metadataConfiguration; }
        set { _metadataConfiguration = value; }
    }
    private ObservableCollection<TaxonomyField> _taxonomyList = new ObservableCollection<TaxonomyField>();
    public ObservableCollection<TaxonomyField> TaxonomyList
    {
        get
        {
            ObservableCollection<TaxonomyField> tempTaxanomy = new ObservableCollection<TaxonomyField>(_taxonomyList);
            tempTaxanomy.Add(null);
            tempTaxanomy.Move(tempTaxanomy.Count - 1, 0);
            foreach (MetadataConfiguration mdConfig in _metadataConfiguration.ToList())
            {
                tempTaxanomy.Remove(mdConfig.Field);
            }
            return tempTaxanomy;
        }
        set
        {
            _taxonomyList = value;
        }
    }

    public class MetadataConfiguration : ViewModelBase
    {

        private TaxonomyField _field;
        [XmlIgnore]
        public TaxonomyField Field
        {
            get { return _field; }
            set
            {
                _field = value;
                _isDirty = true;
                _fieldName = _field == null ? String.Empty : _field.Title;
                _fieldGUID = _field == null ? Guid.Empty : _field.Id;
                _termsetGUID = _field == null ? Guid.Empty : _field.TermSetId;
                OnPropertyChanged("Field");
            }
        }

        private string _fieldName;
        public string FieldName
        {
            get { return _fieldName; }
            set { 
                _fieldName = value;
                OnPropertyChanged("FieldName");
            }
        }

        private Guid _fieldGUID;
        public Guid FieldGUID
        {
            get { return _fieldGUID; }
            set { _fieldGUID = value;
            OnPropertyChanged("FieldGUID");
            }
        }

        private Guid _termsetGUID;
        public Guid TermsetGUID
        {
            get { return _termsetGUID; }
            set { _termsetGUID = value;
            OnPropertyChanged("TermsetGUID");
            }
        }
    }
}

The ViewModel populates the list as follows

_model.TaxonomyList = new ObservableCollection<TaxonomyField>(_lstTaxonomyFileds);

if (_model.MetadataConfig.Count > 0)
{
    foreach (MetadataConfigurationModel.MetadataConfiguration mdConfig in _model.MetadataConfig)
    {
        mdConfig.Field = (from a in _model.TaxonomyList where a.Id == mdConfig.FieldGUID select a).FirstOrDefault();
    }
}

And the xaml is as follows:

<DataGrid AutoGenerateColumns="False" x:Name="dgMetadataConfig" Grid.Row="2" Grid.Column="0" ScrollViewer.VerticalScrollBarVisibility="Auto" 
        ItemsSource="{Binding MetadataConfig, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10,0,0,0" CanUserAddRows="False" VerticalAlignment="Top">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Field Name">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox Width="170" SelectedItem="{Binding Field, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                        ItemsSource="{Binding DataContext.TaxonomyList, Mode=TwoWay, 
                        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},
                        UpdateSourceTrigger=PropertyChanged}" 
                              Margin="2,2,2,2" DropDownOpened="CmbTaxonomyField_DropDownOpened" DisplayMemberPath="Title" SourceUpdated="CmbTaxonomyField_SourceUpdated"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

In the viewmodel I have a list _lstTaxonomyFileds that I am using in populate the TaxonomyList in the model. This list contains say three items "AB", "BC" and "CD". Now the user adds the first row to the grid and have all three options in the combobox and selects "AB" now adds another row and will now have only "BC" and "CD" in the combobox until he deselect "AB" from the first row.


Solution

  • Not an ideal solution but somehow I was able to make it work. Moved the TaxonomyField property in the MetadataConfiguration class, did some linq magic and binded it to the itemsource.