Search code examples
c#wpflistviewcombobox

How to populate ComboBox inside ListView in WPF


Since ComboBox is within CellTemplate I cannot access it and set its ItemsSource. I have a method in other class to pull data from MySql and assign it to the class properties. It works perfect in ComboBox outside ListView, just can't bind it when it's inside ListView.

WPF CODE:

<GridViewColumn Header="Distributor">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <ComboBox x:Name="_distributor"/>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

Solution

  • Hi please try the next:

    Xaml code

           <ListView ItemsSource="{Binding Users}">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate DataType="someBindingExampleSoHelpAttempt:UserModel">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="100"></ColumnDefinition>
                                        <ColumnDefinition Width="200"></ColumnDefinition>
                                        <ColumnDefinition Width="50"></ColumnDefinition>
                                        <ColumnDefinition Width="50"></ColumnDefinition>
                                    </Grid.ColumnDefinitions>
                                    <TextBox Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Text="{Binding Name, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"/>
                                    <TextBox Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Text="{Binding LastName, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"/>
                                    <ComboBox Grid.Column="2"
                                              IsTextSearchEnabled="True"     
                                              IsTextSearchCaseSensitive="False"     
                                              StaysOpenOnEdit="True"    
                                              TextSearch.TextPath="DepartmentName"
                                              ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
                                        AncestorType={x:Type ListView}}, Path=DataContext.Departments}"    
                                              SelectedValue="{Binding Department}"     
                                              DisplayMemberPath="DepartmentName" 
                                              IsEditable="True"
                                              HorizontalAlignment="Stretch"     
                                              VerticalAlignment="Stretch"/>
                                    <ComboBox Grid.Column="3"
                                              IsTextSearchEnabled="True"     
                                              IsTextSearchCaseSensitive="False"     
                                              StaysOpenOnEdit="True"
                                              IsEditable="True"
                                              TextSearch.TextPath="OfficeName"
                                              ItemsSource="{Binding OfficesCollection}"    
                                              SelectedValue="{Binding Office}"     
                                              DisplayMemberPath="OfficeName"      
                                              HorizontalAlignment="Stretch"     
                                              VerticalAlignment="Stretch"/>
                                </Grid>
    
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>
    

    ViewModels and Models

    public class MainViewModel:BaseObservableObject
    {
        private DepartmentModel _selectedDepartment;
        private OfficeModel _selectedOffice;
    
        public MainViewModel()
        {
            Dal = new DataLayer();
            Users = new ObservableCollection<UserModel>();
            Departments = new ObservableCollection<DepartmentModel>(Dal.GetAllDepartments());
            InitUsersCollection();
        }
    
        private void InitUsersCollection()
        {
            if(Departments == null) return;
            Departments.ToList().ForEach(model =>
            {
                model.Offices.ToList().ForEach(officeModel =>
                {
                    if (officeModel.Users == null) return;
                    officeModel.Users.ToList().ForEach(userModel => Users.Add(userModel));
                });
            });
        }
    
        public ObservableCollection<UserModel> Users { get; set; }
    
        public ObservableCollection<DepartmentModel> Departments { get; set; }
    
        private DataLayer Dal { get; set; }
    
    }
    
    public class DataLayer
    {
        public List<DepartmentModel> GetAllDepartments()
        {
            //pull and map your collection sources using your DB service
            //For example:
            return new List<DepartmentModel>
            {
                new DepartmentModel
                {
                    DepartmentId = 1,
                    DepartmentName = "A",
                    Offices = new ObservableCollection<OfficeModel>
                    {
                        new OfficeModel
                        {
                            DepartmentId = 1,
                            OfficeName = "AA",
                            Users = new ObservableCollection<UserModel>(new List<UserModel>
                            {
                                new UserModel {Name = "Avicenna", LastName = "Abu Ali Abdulloh Ibn-Sino"},
                                new UserModel {Name = "Omar", LastName = "Khayyam"},
                                new UserModel {Name = "RAMBAM", LastName = "Moshe ben Maimon"}
                            })
                        },
                        new OfficeModel 
                        {
    
                            DepartmentId = 1, 
                            OfficeName = "AB", 
                            Users = new ObservableCollection<UserModel>(new List<UserModel>
                            {
                                new UserModel {Name = "Leo", LastName = "Tolstoi"},
                                new UserModel {Name = "Anton", LastName = "Chekhov"},
                            })},
                    }
                },
                new DepartmentModel
                {
                    DepartmentId = 2,
                    DepartmentName = "B",
                    Offices = new ObservableCollection<OfficeModel>
                    {
                        new OfficeModel
                        {
                            DepartmentId = 2, OfficeName = "BA",
                            Users = new ObservableCollection<UserModel>(new List<UserModel>
                            {
                                new UserModel {Name = "B", LastName = "O"},
                                new UserModel {Name = "B", LastName = "N"},
                            }),
                        },
                        new OfficeModel
                        {
                            DepartmentId = 2, OfficeName = "BB",
                            Users = new ObservableCollection<UserModel>(new List<UserModel>
                            {
                                new UserModel {Name = "John", LastName = "Walker"},
                                new UserModel {Name = "Gregory", LastName = "Rasputin"},
                            }),
                        },
                    }
                },
                new DepartmentModel
                {
                    DepartmentId = 3,
                    DepartmentName = "C",
                    Offices = new ObservableCollection<OfficeModel>
                    {
                        new OfficeModel {DepartmentId = 3, OfficeName = "CA"},
                        new OfficeModel {DepartmentId = 3, OfficeName = "CB"},
                        new OfficeModel {DepartmentId = 3, OfficeName = "CC"}
                    }
                }
            };
        }
    }
    
    public class OfficeModel:BaseObservableObject
    {
        private int _departmentModel;
        private string _officeName;
        private DepartmentModel _department;
        private ObservableCollection<UserModel> _users;
    
        public int DepartmentId
        {
            get { return _departmentModel; }
            set
            {
                _departmentModel = value;
                OnPropertyChanged();
            }
        }
    
        public DepartmentModel Department
        {
            get { return _department; }
            set
            {
                _department = value;
                OnPropertyChanged();
            }
        }
    
        public string OfficeName
        {
            get { return _officeName; }
            set
            {
                _officeName = value;
                OnPropertyChanged();
            }
        }
    
        public ObservableCollection<UserModel> Users
        {
            get { return _users; }
            set
            {
                _users = value;
                OnPropertyChanged(()=>Users);
            }
        }
    }
    
    public class DepartmentModel:BaseObservableObject
    {
    
        private string _departmentName;
    
        public string DepartmentName
        {
            get { return _departmentName; }
            set
            {
                _departmentName = value;
                OnPropertyChanged();
            }
        }
    
        public int DepartmentId { get; set; }
    
        public ObservableCollection<OfficeModel> Offices { get; set; }
    }
    
    public class UserModel:BaseObservableObject
    {
        private string _name;
        private string _lastName;
        private DepartmentModel _department;
        private OfficeModel _office;
    
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                OnPropertyChanged();
            }
        }
    
        public string LastName
        {
            get { return _lastName; }
            set
            {
                _lastName = value;
                OnPropertyChanged();
            }
        }
    
        public DepartmentModel Department
        {
            get { return _department; }
            set
            {
                _department = value;
                OnPropertyChanged();
                OnPropertyChanged(()=>OfficesCollection);
            }
        }
    
        public ObservableCollection<OfficeModel> OfficesCollection
        {
            get { return Department.Offices; }
        }
    
        public OfficeModel Office
        {
            get { return _office; }
            set
            {
                _office = value;
                OnPropertyChanged();
            }
        }
    }
    

    ListView's holding control DataContext declaration in XAML

        <!--This User Control Holds The ListView as one of it's Contents-->
        <UserControl.DataContext>
            <someBindingExampleSoHelpAttempt:MainViewModel/>
        </UserControl.DataContext>
    

    Useful MVVM links (google the mvvm there are a tones of information) 1. WPF/MVVM Quick Start Tutorial. 2. MVVM: Tutorial from start to finish. 3. Learn how to correctly implement the MVVM pattern following a set of simple steps.

    Let me know if you need more help.

    Regards.