Cantinou
Cantinou

Reputation: 136

Filter a dataGridComboBox column from a ComboBox

First I choose a supplier in a ComboBox Column and then only the references from this supplier should populate the dataGridComboBox column.

I thought I know how to do it, but obviously something is missing. I don't have any error but my dataGridComboBox column is still empty.

View

<ComboBox x:Name="supplierComboBox"
                      Margin="5" 
                      ItemsSource="{Binding Collection, Source={StaticResource supplier}}" 
                      DisplayMemberPath="supplier"
                      SelectedItem="{Binding Supplier,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                      SelectedValuePath="idfoodSupplier"
                      Text="{Binding SupplierText, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                      Width="160"/>
<DataGrid x:Name="dataGridInvoice" 
                      ItemsSource="{Binding Collection}" 
                      AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridComboBoxColumn Header="Ref Supplier"
                                            ItemsSource="{Binding Reference, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                            DisplayMemberPath="refsup" 
                                            SelectedValueBinding="{Binding refSup}" 
                                            SelectedValuePath="refsup"
                                            Width="*"/>  
                </DataGrid.Columns>
            </DataGrid>

ViewModel

public class InvoiceViewModel : ViewModelBase
    {


        public Context ctx = new Context();

        Invoice invoice;

        public InvoiceViewModel()
        {
            Collection = new ObservableCollection<PreInvoice>();
        }

        private ObservableCollection<PreInvoice> collection;

        public ObservableCollection<PreInvoice> Collection
        {
            get
            {
                return collection;
            }
            set
            {
                collection = value;
                OnPropertyChanged("Collection");
            }
        }

        private foodSupplier _supplier;
        public foodSupplier Supplier
        {
            get
            {
                return _supplier;
            }
            set
            {
                _supplier = value;
                OnPropertyChanged("Supplier");
                Reference = new List<product>();
                Reference = (from p in ctx.products
                              where p.supplier == _supplier.idfoodSupplier
                              select p).ToList();
            }
        }

        private List<product> _reference;

        public List<product> Reference
        {
            get
            {
                return _reference;
            }
            set
            {
                _reference = value;
                OnPropertyChanged("Reference");
            }
        }


        public class PreInvoice : ViewModelBase
        {
            public string refSup {get; set;}


        }
    }

Product Model

public partial class product
{
    public int idproduct { get; set; }
    public Nullable<int> supplier { get; set; }
    public string refsup { get; set; }
    public string description { get; set; }

    public virtual foodSupplier foodSupplier { get; set; }

}

Upvotes: 0

Views: 608

Answers (1)

user1672994
user1672994

Reputation: 10839

Since DataGridComboBoxColumn or any other supported data grid columns are not part of visual tree of datagrid so they don't inherit the DataContext of datagrid. Since, they don't lie in visual tree so any try to get DataContext using RelativeSource won't work.

Solution - You can create a proxy element to bind the data context of window; use that proxy element to bind the ItemsSource of DataGridComboBoxColumn. For ex :

<Window x:Class="WpfApplication10.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication10"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        d:DataContext="{d:DesignInstance local:Vm, IsDesignTimeCreatable=True}">
    <Grid>
        <Grid.Resources>
            <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
            <ComboBox x:Name="supplierComboBox"
                      Margin="5" 
                      ItemsSource="{Binding Collection, Source={StaticResource supplier}}" 
                      DisplayMemberPath="supplier"
                      SelectedItem="{Binding Supplier,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                      SelectedValuePath="idfoodSupplier"
                      Text="{Binding SupplierText, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                      Width="160"/>

        <ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"></ContentControl>
        <DataGrid x:Name="dataGridInvoice" 
                  ItemsSource="{Binding Collection}" 
                  AutoGenerateColumns="False">
            <DataGrid.Columns>
             <DataGridComboBoxColumn Header="Ref Supplier"
                                            ItemsSource="{Binding DataContext.Reference, Source={StaticResource ProxyElement}}"
                                            DisplayMemberPath="refsup" 
                                            SelectedValueBinding="{Binding refSup}" 
                                            SelectedValuePath="refsup"
                                            Width="*"/>  
            </DataGrid.Columns>

            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Upvotes: 1

Related Questions