0

I can't find a working solution to my issue

I have a datagrid binded to an object collection. one of my object property is used as an index in a collection. The autogenerated combobox column "Type" displays the "label" associated to this index.

I need to update another property which is an index too in that same object. I use this code to add the combobox in the AutogeneratingColumn event :

  public partial class LedTableEditor : MetroWindow, INotifyPropertyChanged
  {
    private object _sender;
    public Dictionary<int, string> IdColors = new Dictionary<int, string>();
    public ObservableCollection<Xceed.Wpf.Toolkit.ColorItem> MarshallingColors = new ObservableCollection<Xceed.Wpf.Toolkit.ColorItem>();
    private Dictionary<int, string> cbTypeVals = new Dictionary<int, string>();
    private Dictionary<UInt16, string> cbSrcValueVals = new Dictionary<UInt16, string>();
    private Dictionary<UInt16, string> cbDiagVals = new Dictionary<UInt16, string>();

    private List<string> ListeData = new List<string>();
    private List<string> ListeDiag = new List<string>();

    private int maxLeds = 16;
    private XapLedVals led;

    public LedTableEditor(object senderParam)
    {
         -----
    }



 private void DgLedTable_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
 {

        if (e.PropertyName == "Type")
        {
            DataGridComboBoxColumn cbType = new DataGridComboBoxColumn();
            cbType.EditingElementStyle = new Style(typeof(ComboBox))
            {
                Setters =
                {
                    new EventSetter(Selector.SelectionChangedEvent, new SelectionChangedEventHandler(OnComboBoxSelectionChanged))
                }
            };

            e.Column = cbType;
            cbType.ItemsSource = cbTypeVals; // new List<string> { eLedType.ALERTE.ToString(), eLedType.DIAG.ToString(), eLedType.TRIGGER.ToString() };
            cbType.DisplayMemberPath = "Value";
            cbType.SelectedValuePath = "Key";
            cbType.SelectedValueBinding = new Binding("Type");
            e.Column.Header = "Type";
            e.Column.CellStyle = new Style(typeof(DataGridCell));
            e.Column.CellStyle.Setters.Add(new Setter(DataGridCell.HorizontalAlignmentProperty, HorizontalAlignment.Stretch));

        }

        if (e.PropertyName == "Binding")
        {
            DataGridComboBoxColumn cbBinding = new DataGridComboBoxColumn();
            BindingOperations.SetBinding(cbBinding, DataGridComboBoxColumn.ItemsSourceProperty, new Binding("Source") { Source = this });

            e.Column = cbBinding;
            cbBinding.ItemsSource = cbSrcValueVals;
            cbBinding.DisplayMemberPath = "Value";
            cbBinding.SelectedValuePath = "Key";
            cbBinding.SelectedValueBinding = new Binding("Binding");
            e.Column.Header = "Binding";
            e.Column.CellStyle = new Style(typeof(DataGridCell));
            e.Column.CellStyle.Setters.Add(new Setter(DataGridCell.HorizontalAlignmentProperty, HorizontalAlignment.Stretch));
        }
----
   }

the combobox "Type" item source is a dictionary :

private Dictionary<int, string> cbTypeVals = new Dictionary<int, string>();

I need to update this "Binding" combobox item source, which is autogenerated too in the same datagrid :

if (e.PropertyName == "Binding")
{
    AutoCommitComboBoxColumn cb = new AutoCommitComboBoxColumn();
    e.Column = cb;
    cb.ItemsSource = cbSrcValueVals;
    cb.DisplayMemberPath = "Value";
    cb.SelectedValuePath = "Key";
    cb.SelectedValueBinding = new Binding("Binding");
    e.Column.Header = "Binding";
    e.Column.CellStyle = new Style(typeof(DataGridCell));
    e.Column.CellStyle.Setters.Add(new Setter(DataGridCell.HorizontalAlignmentProperty, HorizontalAlignment.Stretch));
    }

the combobox "Binding" item source is a dictionary :

private Dictionary<UInt16, string> cbSrcValueVals = new Dictionary<UInt16, string>();

it should be updated with this one :

private Dictionary<UInt16, string> cbDiagVals = new Dictionary<UInt16, string>();

The event is correctly fired, but I can't find a way to update "Binding" combobox items.

private void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    DgLedTable.CurrentCell = new DataGridCellInfo(DgLedTable.SelectedIndex, DgLedTable.Columns[1]);
}

Thank you for your help.

Edit here is an image of the screen with items in ComboBox "Type" :

enter image description here

Edit, code added for property changed :

    private System.Collections.IEnumerable _source;
    public System.Collections.IEnumerable Source
    {
        get { return _source; }
        set { _source = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
       // DgLedTable.CurrentCell = new DataGridCellInfo(DgLedTable.SelectedIndex, DgLedTable.Columns[1]);
        Source = cbDiagVals;
    }
Alexus
  • 276
  • 1
  • 5
  • 22
  • So you want to change the ItemsSource of the "Binding" ComboBox from "cbSrcValueVals" to some other collection, right? What collection do you want to use as the new ItemsSource then? – mm8 Feb 10 '17 at 13:21
  • yes exactly, if combo box type is set to 2, I need to update "Binding" combobox with another dictionnary : `private Dictionary cbDiagVals = new Dictionary();` – Alexus Feb 10 '17 at 13:23

1 Answers1

1

If you create a source property and bind the ItemsSource property of the "Binding" ComboBox to this one you could set this property to a new collection in the "Type" ComboBox's SelectionChanged event handler.

The window - or in whatever type your code is defined - must implement the INotifyPropertyChanged interface for this to work:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private Dictionary<int, string> cbTypeVals = new Dictionary<int, string>();
    private Dictionary<UInt16, string> cbSrcValueVals = new Dictionary<UInt16, string>();
    private Dictionary<UInt16, string> cbDiagVals = new Dictionary<UInt16, string>();

    public MainWindow()
    {
        InitializeComponent();
        _source = cbTypeVals;
        //...
    }

    private System.Collections.IEnumerable _source;
    public System.Collections.IEnumerable Source
    {
        get { return _source; }
        set { _source = value; OnPropertyChanged(); }
    }


    private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        if (e.PropertyName == "Binding")
        {
            AutoCommitComboBoxColumn cb = new AutoCommitComboBoxColumn();
            e.Column = cb;

            //bind the ItemsSource property to the Source property of the window here...
            cb.SetBinding(AutoCommitComboBoxColumn.ItemsSourceProperty, new Binding("Source") { Source = this });

            cb.ItemsSource = cbSrcValueVals;
            cb.DisplayMemberPath = "Value";
            cb.SelectedValuePath = "Key";
            cb.SelectedValueBinding = new Binding("Binding");
            e.Column.Header = "Binding";
            e.Column.CellStyle = new Style(typeof(DataGridCell));
            e.Column.CellStyle.Setters.Add(new Setter(DataGridCell.HorizontalAlignmentProperty, HorizontalAlignment.Stretch));
        }
        //...
    }

    private void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        //set the value of the Source property to a new collection and raise the PropertyChanged event here...
        Source = cbDiagVals;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    //...
}
mm8
  • 163,881
  • 10
  • 57
  • 88
  • 1
    OK, I forgot to remove the `cbBinding.ItemsSource = cbSrcValueVals;`code line... it was reset every time. Thank you for your help and elegant solution... and patience ! – Alexus Feb 10 '17 at 16:33
  • I have another question : How could I set the source of the "Binding" combo when I re-open the Window. By default the"Binding" ComboBox is set with the first dictionnary cbSrcValueVals. – Alexus Feb 13 '17 at 10:48
  • 1
    Deleting the additional comments here. @Alexus, If you have another question, please ask it by clicking the [Ask Question](//stackoverflow.com/questions/ask) button, along with a [mcve]. You can reference this question in your new question, But try to check the related posts before posting one. – Bhargav Rao Feb 13 '17 at 10:53