1
votes

I'm having an issue with a WPF Datagrid's DataGridTemplateColumn and updating the items that display on the ComboBox based off of a user's interaction. Since the program is database bound, it doesn't make sense to load all items from the database at once, instead it uses the Entity Framework to pull what the user requests at a given moment.

To facilitate a view that's compact, the next/previous buttons are on the combobox template, as well as search functionality, the issue I'm running into is: When the templated comboboxes are in a datagrid, next/previous does not function. Outside of a datagrid they function properly.

I've even tried using the knowledge that the Combobox is present and manually pulled it from the visual tree by doing a search for that combobox by name, pulled its binding for the itemssource and told it to update. Nothing happens.

Here is an image of what I mean below: enter image description here

The display DOES update once I select a new cell; however, since I capture when it's about to enter edit mode and update the list to contain the item selected (for binding purposes, ComboBoxes don't like to have a selected item that's not in its item set.)

As you can imagine, this is a rather big issue. It's difficult to continue developing this until an resolution is found. Is this a known issue with Datagrids? If so, I might have to roll my own. Which I don't want to do for performance reasons, I'm no MVVM expert, the only reason the UI looks as it does is it's basically defining itself, within itself.

1

1 Answers

0
votes

I'm daft, that's the problem:

private static void UpdateComboDropdown(string comboboxName, DataGrid dataGrid)
{
    /* *
     * I think CurrentItem is used in this instance because 
     * it's a single cell selection mode?
     * *
     * I CBA to check.
     * */
    var selectedRow = dataGrid.ItemContainerGenerator.ContainerFromItem(dataGrid.CurrentItem) as DataGridRow;
    if (selectedRow != null)
    {
        DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(selectedRow);
        if (presenter != null)
        {

            var visualComboBox = presenter.FindChild<ComboBox>(comboboxName);
            if (visualComboBox != null)
            {
                var binding = visualComboBox.GetBindingExpression(ComboBox.ItemsSourceProperty);
                if (binding != null)
                    binding.UpdateTarget();
            }
            var popupPart = visualComboBox.FindChild<Popup>("PART_Popup");
            if (popupPart != null && popupPart.Child != null)
            {
                //Popup has one child, reports zero children, so: search on its child.
                var previous = popupPart.Child.FindChild<Button>("PreviousButton");
                if (previous != null)
                {
                    var previousIsEnabledBinding = previous.GetBindingExpression(Button.IsEnabledProperty);
                    if (previousIsEnabledBinding != null)
                        previousIsEnabledBinding.UpdateTarget();
                }
                var next = popupPart.Child.FindChild<Button>("NextButton");
                if (next != null)
                {
                    var nextIsEnabledBinding = next.GetBindingExpression(Button.IsEnabledProperty);
                    if (nextIsEnabledBinding != null)
                        nextIsEnabledBinding.UpdateTarget();
                }
            }
        };
    }
}

I was telling it to update the ItemsSource of the combobox, not the other way around. As for why the relationship isn't automatically updating, I don't know. Now to find out how to update the constituent elements of the combobox controls in its dropdown. Likely will involve getting its PART_Popup, then the next/previous buttons and their respective bindings. This is annoying.

Edit: Updated the answer with the full solution.