0

I am currently working on a UserControl which uses a DataGrid which has combo boxes in it. I am trying to bind the drop down to a list of values set by the main window which is using the UserControl.

In MainWindow I have:

<local:AdvancedFilter
            AddRowImageSource="/Images/add_16.png"
            DeleteRowImageSource="/Images/delete.png"
            Properties="{Binding Properties}"></local:AdvancedFilter>

And Properties in MainWindow is defined as:

private ObservableCollection<PropertyEntry> properties = new ObservableCollection<PropertyEntry>();
        
public ObservableCollection<PropertyEntry> Properties
{
    get
    {
        return properties;
    }
    set
    {
        properties = value;
        OnPropertyChanged(nameof(Properties));
    }
}

And the collection of values is populated in a method called SetupTestData which is called in the MainWindow() constructor method. PropertyEntry is defined as:

public class PropertyEntry
{
    public string OriginalPropertyName { get; set; }
    public string DisplayPropertyName { get; set; }
    public IList<string> PickList { get; set; }
}

Now in the user control itself I have the data grid defined as (just showing the relevant part):

<DataGrid Name="OperatorDataGrid" CanUserAddRows="false" AutoGenerateColumns="False" MinHeight="250" LoadingRow="DataGrid_LoadingRow" EnableRowVirtualization="False">
    <DataGrid.Columns>
        <DataGridComboBoxColumn Header="Property" MinWidth="100" 
                                        ItemsSource="{Binding Properties, RelativeSource={RelativeSource AncestorType=UserControl}}" 
                                        SelectedValuePath="OriginalPropertyName" 
                                        DisplayMemberPath="DisplayPropertyName">
            <DataGridComboBoxColumn.EditingElementStyle>
                <Style TargetType="{x:Type ComboBox}">
                    <EventSetter Event="SelectionChanged" Handler="PropertyName_SelectionChanged"/>
                </Style>
            </DataGridComboBoxColumn.EditingElementStyle>
        </DataGridComboBoxColumn>
    </DataGrid.Columns>
</DataGrid>

And in the code-behind for the user control there is:

public static readonly DependencyProperty PropertiesProperty =
    DependencyProperty.Register("Properties", typeof(ObservableCollection<PropertyEntry>), typeof(AdvancedFilter),
        new PropertyMetadata(new PropertyChangedCallback(OnItemsSourcePropertyChanged)));

public ObservableCollection<PropertyEntry> Properties
{
    get { return (ObservableCollection<PropertyEntry>)GetValue(PropertiesProperty); }
    set { SetValue(PropertiesProperty, value); }
}

And in the user control's constructor:

public AdvancedFilter()
{
    InitializeComponent();
    SetDefaults();

    FilterRows.Add(new FilterRow());
    OperatorDataGrid.ItemsSource = FilterRows;

    DataContext = this;
}

The FilterRows collection is for all the rows in the data grid as user's add new rows. However, the combo box column should be a list of values that comes from the binding. When viewing the code though, it appears that the Properties collection in the user control never receives the list from MainWindow. I also tried setting the ItemsSource property of the data grid to a static resource that I defined as:

<CollectionViewSource x:Key="PropertyList" Source="{Binding Properties}"/>

But this didn't work either.

I am sure I am missing something simple but cannot figure out what it is. Any help would be greatly appreciated. Thank you.

TL;DR: Trying to bind a combo box, in a data grid, to a list of values that is different from the data grid's ItemsSource property and that this list comes from a binding that is defined where the user control is used in a window.

uvr
  • 515
  • 4
  • 12
Dominick
  • 322
  • 1
  • 3
  • 16
  • Does `OnItemsSourcePropertyChanged` get called? What's the `DataContext` of the window? – mm8 Apr 19 '21 at 14:14
  • Remove `DataContext = this;` from the UserControl's constructor. – Clemens Apr 19 '21 at 14:14
  • @Clemens If I remove ```DataContext = this;``` it still doesn't work. However, if I change the ```ItemsSource``` binding to use the static resource, the list shows but if I select an item in the combo box and then click on a different cell, the selected item disappears to that the column is empty. – Dominick Apr 19 '21 at 14:24
  • @mm8 The data context of the main window is itself. – Dominick Apr 19 '21 at 14:26
  • You do not also set the UserControl's DataContext in its XAML? Take a look at the Output Window in Visual Studio for data binding error messages when you debug the application. – Clemens Apr 19 '21 at 14:35
  • @Clemens There is no binding error. If I bind the combobox to a static resource, they come up but then if I change the selected value of the CB in one row, they all change to the same value. If I try setting the binding using a relativesource, the list comes up but if I select an item in the CB and click on another cell, then nothing is set in the CB. No idea what is going on. – Dominick Apr 19 '21 at 14:44
  • I was able to resolve it (at least for now) by using a ```DataGridTemplateColumn``` with a regular combobox instead of the ```DataGridComboBoxColumn```. Thank you for the trying to help. I appreciate it. – Dominick Apr 19 '21 at 14:48
  • There does not seem to be a [SelectedValueBinding](https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.datagridcomboboxcolumn.selectedvaluebinding?view=net-5.0). Without that, setting SelectedValuePath is pointless. The equivalent property in a ComboBox is SelectedValue. You don't need to attach a SelectionChanged event handler. – Clemens Apr 19 '21 at 14:48

0 Answers0