Selected Item in ComboBox wpf with Binding

Anja 426 Reputation points
2021-04-01T19:25:47.69+00:00

I have a listview, when selecting the listview I make a binding to an SelectedCategory property.

When binding to Checkbox, Textbox an so works fine, but I can't find the right combination for the ComboBox no matter what I try.

I know for sure, that the ProjectName exists AND is binded correctly to the SelectedCategory (I have made a button and before that display the ProjectId and ProjectName).

I hope one of You can see, where I'm doing something wrong

Best regards
Simsen :-)

My ListView looks like this

<ListView x:Name="LivCategories" ItemsSource="{Binding Categories_GetActive}" SelectedItem="{Binding SelectedCategory}" Grid.Row="0" Grid.Column="0">
                        <ListView.View>
                            <GridView>
                                <GridViewColumn Header="Id" Width="50" DisplayMemberBinding="{Binding CategoryId}"/>
                                <GridViewColumn Header="Navn" Width="250"  DisplayMemberBinding="{Binding CategoryName}"/>
                                <GridViewColumn Header="Global" Width="50"  DisplayMemberBinding="{Binding CategoryIsGlobal}"/>
                                <GridViewColumn Header="Project" Width="150"  DisplayMemberBinding="{Binding ProjectName}"/>
                                <GridViewColumn Header="ProjectId" Width="0"  DisplayMemberBinding="{Binding ProjectId}" />
                            </GridView>
                        </ListView.View>
                    </ListView>

And here I show you a Checkbox witch works perfectly
<CheckBox x:Name="CbxCategoryActiveActive" Content="Inaktiv:" Grid.Row="4" Grid.Column="1" Margin="0 0 168 0" VerticalAlignment="Center"
HorizontalContentAlignment="Left" Grid.ColumnSpan="2"
IsChecked="{Binding ElementName=LivCategories, Path = SelectedValue.CategoryIsObsolete, Mode = TwoWay}" />

One of the ways I have tried for the ComboBox you can see here
<ComboBox x:Name="CbxProject" Text="Projekt" Grid.Row="5" Grid.Column="2" HorizontalContentAlignment="Left" VerticalContentAlignment="Center"
ItemsSource="{Binding Path=Projects_GetActive}" DisplayMemberPath="ProjectName"
SelectedValuePath="LivCategories"
SelectedItem="{Binding ElementName=LivCategories, Path= SelectedValue.ProjectName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsSynchronizedWithCurrentItem="True">
</ComboBox>

And here You can see the SelectedCategory

private Category _selectedCategory;
        public MyICommand DeleteCommand { get; set; }

        public Category SelectedCategory
        {
            get
            {
                return _selectedCategory;
            }

            set
            {
                _selectedCategory = value;
                DeleteCommand.RaiseCanExecuteChanged();
            }
        }
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,762 questions
0 comments No comments
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,321 Reputation points
    2021-04-05T09:42:11.197+00:00

    Hi,
    if you want select Project in ComboBox bind Text property like in following demo:

    XAML:

    <Window x:Class="WpfApp1.Window035"  
            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:WpfApp035"  
            mc:Ignorable="d"  
            Title="MainWindow" Height="450" Width="800">  
      <Window.DataContext>  
        <local:ViewModel/>  
      </Window.DataContext>  
      <Grid>  
        <Grid.RowDefinitions>  
          <RowDefinition/>  
          <RowDefinition Height="auto"/>  
          <RowDefinition Height="auto"/>  
          <RowDefinition Height="auto"/>  
          <RowDefinition Height="auto"/>  
        </Grid.RowDefinitions>  
        <ListView x:Name="LivCategories"   
                  ItemsSource="{Binding Categories_GetActive}"   
                  SelectedItem="{Binding SelectedCategory}" Grid.Row="0" Grid.Column="0">  
          <ListView.View>  
            <GridView>  
              <GridViewColumn Header="Id" Width="50" DisplayMemberBinding="{Binding CategoryId}"/>  
              <GridViewColumn Header="Navn" Width="250"  DisplayMemberBinding="{Binding CategoryName}"/>  
              <GridViewColumn Header="Global" Width="50"  DisplayMemberBinding="{Binding CategoryIsGlobal}"/>  
              <GridViewColumn Header="Project" Width="150"  DisplayMemberBinding="{Binding ProjectName}"/>  
              <GridViewColumn Header="ProjectId" Width="0"  DisplayMemberBinding="{Binding ProjectId}" />  
            </GridView>  
          </ListView.View>  
        </ListView>  
      
        <!--And here I show you a Checkbox witch works perfectly-->  
        <CheckBox Content="Inaktiv:" Grid.Row="1"  
                  IsChecked="{Binding ElementName=LivCategories, Path=SelectedValue.CategoryIsObsolete, Mode=TwoWay}" />  
      
        <!--One of the ways I have tried for the ComboBox you can see here-->  
        <ComboBox Grid.Row="2"  
                  ItemsSource="{Binding Path=Projects_GetActive}" DisplayMemberPath="ProjectName"  
                  Text="{Binding ElementName=LivCategories, Path= SelectedValue.ProjectName}"/>  
          
      </Grid>  
    </Window>  
    

    And classes:

    using System.Collections.ObjectModel;  
    using System.ComponentModel;  
    using System.Windows;  
    using System.Windows.Data;  
           
    namespace WpfApp035  
    {  
      public class ViewModel  
      {  
        public ViewModel()  
        {  
          ObservableCollection<Category> colCA = new ObservableCollection<Category>();  
          colCA.Add(new Category() { CategoryId = 1, CategoryIsGlobal = true, CategoryIsObsolete=false, CategoryName = "Cat 1", ProjectId = 11, ProjectName = "Project 11" });  
          colCA.Add(new Category() { CategoryId = 2, CategoryIsGlobal = false, CategoryIsObsolete = false, CategoryName = "Cat 2", ProjectId = 12, ProjectName = "Project 12" });  
          colCA.Add(new Category() { CategoryId = 3, CategoryIsGlobal = true, CategoryIsObsolete = false, CategoryName = "Cat 3", ProjectId = 13, ProjectName = "Project 13" });  
          colCA.Add(new Category() { CategoryId = 4, CategoryIsGlobal = false, CategoryIsObsolete = true, CategoryName = "Cat 4", ProjectId = 14, ProjectName = "Project 14" });  
          colCA.Add(new Category() { CategoryId = 5, CategoryIsGlobal = true, CategoryIsObsolete = false, CategoryName = "Cat 5", ProjectId = 15, ProjectName = "Project 15" });  
          cvsCA.Source = colCA;  
          //  
          ObservableCollection<Project> colPA = new ObservableCollection<Project>();  
          colPA.Add(new Project() { ProjectName = "Project 11" });  
          colPA.Add(new Project() { ProjectName = "Project 12" });  
          colPA.Add(new Project() { ProjectName = "Project 13" });  
          colPA.Add(new Project() { ProjectName = "Project 14" });  
          colPA.Add(new Project() { ProjectName = "Project 15" });  
          cvsPA.Source = colPA;  
        }  
        private CollectionViewSource cvsCA = new CollectionViewSource();  
        public ICollectionView Categories_GetActive { get => cvsCA.View; }  
        public Category SelectedCategory { get; set; }  
        private CollectionViewSource cvsPA = new CollectionViewSource();  
        public ICollectionView Projects_GetActive { get => cvsPA.View; }  
      }  
      
      public class Category  
      {  
        public int CategoryId { get; set; }  
        public string CategoryName { get; set; }  
        public bool CategoryIsGlobal { get; set; }  
        public string ProjectName { get; set; }  
        public int ProjectId { get; set; }  
        public bool CategoryIsObsolete { get; set; }  
      }  
      
      public class Project  
      {  
        public string ProjectName { get; set; }  
      }  
    }  
    

    Result:

    84491-x.gif


2 additional answers

Sort by: Most helpful
  1. DaisyTian-1203 11,621 Reputation points
    2021-04-02T04:16:29.417+00:00

    I don't know the details of your classes, so I created test classes for binding. I use a Enum and custom class to bind data for two ComboBoxs in ListView for you. Please check and let me know if you have any question.
    Add xmlns:sys="clr-namespace:System;assembly=mscorlib" in Xaml:

     <Window.Resources>  
            <ObjectDataProvider x:Key="SelectedCat" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">  
                <ObjectDataProvider.MethodParameters>  
                    <x:Type Type="local:SelectedCategory"></x:Type>  
                </ObjectDataProvider.MethodParameters>  
            </ObjectDataProvider>  
        </Window.Resources>  
        <Grid>  
            <ListView x:Name="listView1" ItemsSource="{Binding}" >  
                <ListView.View>  
                    <GridView>  
                        <GridViewColumn Header="Id" Width="80" DisplayMemberBinding="{Binding CategoryId}" />  
                        <GridViewColumn Header="Navn" Width="80" DisplayMemberBinding="{Binding CategoryName}"/>  
                        <GridViewColumn Header="Global" Width="80"  DisplayMemberBinding="{Binding CategoryIsGlobal}" />  
                        <GridViewColumn Header="Project" Width="80"  DisplayMemberBinding="{Binding ProjectName}"/>  
                        <GridViewColumn Header="ProjectId" Width="80"  DisplayMemberBinding="{Binding ProjectId}"/>  
      
                        <GridViewColumn Header="SelectedCat2">  
                            <GridViewColumn.CellTemplate>  
                                <DataTemplate>  
                                    <ComboBox Width="100" SelectedItem="{Binding testSelected}"  ItemsSource="{Binding testSelecteds}"  DisplayMemberPath="Name" SelectedValue="Value"></ComboBox>  
                                </DataTemplate>  
                            </GridViewColumn.CellTemplate>  
                        </GridViewColumn>  
      
                        <GridViewColumn Header="SelectedCat">  
                            <GridViewColumn.CellTemplate>  
                                <DataTemplate>  
                                    <ComboBox Width="100" SelectedItem="{Binding SelectedCategory}"  ItemsSource="{Binding Source={StaticResource SelectedCat}}"></ComboBox>  
                                </DataTemplate>  
                            </GridViewColumn.CellTemplate>  
                        </GridViewColumn>  
                    </GridView>  
                </ListView.View>  
            </ListView>  
        </Grid>  
    

    The cs code is:

    public partial class MainWindow : Window  
        {  
            public MainWindow()  
            {  
                InitializeComponent();  
                initList();  
            }  
            public void initList()  
            {  
                List<testSelected> Ltselecteds = new List<testSelected>(){  
                new testSelected() { Name = "SelName1",Value = "Value1"},  
                new testSelected() { Name = "SelName2",Value = "Value2"},  
                new testSelected() { Name = "SelName3",Value = "Value3"}  
                };  
      
      
                List<MyModel> listBook = new List<MyModel>();  
                for (int i = 0; i < 15; i++)  
                {  
                    if (i / 2 == 0)  
                    {  
                        listBook.Add(new MyModel()  
                        {  
                            testSelecteds =Ltselecteds,  
                            CategoryId = "00" + i.ToString(),  
                            CategoryName = "testBook" + i,  
                            CategoryIsGlobal = "Math",  
                            ProjectName = "qiaobus",  
                            ProjectId = "pid" + i.ToString(),  
                            SelectedCat = SelectedCategory.Category1  
                        });  
      
                    }  
                    else  
                    {  
                        listBook.Add(new MyModel()  
                        {  
                            testSelecteds =Ltselecteds,  
                            CategoryId = "00" + i.ToString(),  
                            CategoryName = "testBook" + i,  
                            CategoryIsGlobal = "Math",  
                            ProjectName = "qiaobus",  
                            ProjectId = "pid" + i.ToString(),  
                            SelectedCat = SelectedCategory.Category2  
                        });  
      
                    }  
                }  
                listView1.ItemsSource = listBook;  
            }  
        }  
        public class MyModel  
        {  
            public string CategoryId { get; set; }  
            public string CategoryName { get; set; }  
            public string CategoryIsGlobal { get; set; }  
            public string ProjectName { get; set; }  
            public string ProjectId { get; set; }  
            public SelectedCategory SelectedCat { get; set; }  
      
            public List<testSelected> testSelecteds { get; set; } = new List<testSelected>();  
      
        }  
      
        public enum SelectedCategory { Category1, Category2, Category3 }  
      
        public class testSelected  
        {  
            public string Name { get; set; }  
            public string Value { get; set; }  
        }  
    

    The result picture is:
    83858-2.gif


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Anja 426 Reputation points
    2021-04-02T14:20:43.753+00:00

    Hi Thank you for your answer.

    I'm so sorry that I haven't been clear enough.

    I have a ListView, that shows the active Category list. I also have some controls. These controls should show the values from the selected row in the ListView.

    That works fine except from the control combobox. I have made a a SelectedCategory in the CategoryViewModel, and it shows the selected value for the row I have selected.

    I populate the combobox with a list of Projects. But when selecting a row in the ListView it doesn't show the specific Project in the comboBox.

    I'm unsure if it is because that the ProjectId is a foreign key in the Category list?

    I'm pretty sure, it hasn't anything with the code behind because I have made to textboxes to be sure, I get the selected values for the selected row in the ListView - and these shows the correct projectId and projectName. So it has to do with this specifc line - I don't get it right;

    <ComboBox x:Name="CbxProject" Text="Projekt" Grid.Row="5" Grid.Column="2" HorizontalContentAlignment="Left"  VerticalContentAlignment="Center"
                                          ItemsSource="{Binding Projects_GetActive}" DisplayMemberPath="ProjectName"
                                          SelectedItem="{Binding  SelectedValue.ProjectName}">
    

    I have tried your 2 suggestions and with no success
    This doesn't do anything with the combobox. It shows correctly the 4 rows but when clicking on a specific row it doesn't show the specific Project.

    <ComboBox x:Name="CbxProject" Text="Projekt" Grid.Row="5" Grid.Column="2" HorizontalContentAlignment="Left"  VerticalContentAlignment="Center"
                                          ItemsSource="{Binding Projects_GetActive}" DisplayMemberPath="ProjectName"
                                          SelectedItem="{Binding  SelectedValue.ProjectId}">
    

    This one gets me an error " The resource could not be resolved.

    <ComboBox Width="100" SelectedItem="{Binding SelectedCategory}"  ItemsSource="{Binding Source={StaticResource SelectedCat}}"></ComboBox>
    

    Here I have made 2 textboxes (which shows the correct projectid and projectName when activating the row in the listview;

    And the combobox that dos not change anything.

    <ComboBox x:Name="CbxProject" Text="Projekt" Grid.Row="5" Grid.Column="2" HorizontalContentAlignment="Left"  VerticalContentAlignment="Center"
                                          ItemsSource="{Binding Projects_GetActive}" DisplayMemberPath="ProjectName"
                                          SelectedItem="{Binding  SelectedValue.ProjectName}">
                                </ComboBox>
    
                                <TextBox x:Name="TxtProjectId" Margin="0 0 8 0" Text="{Binding ElementName=LivCategories, Path = SelectedValue.ProjectId, Mode = TwoWay}" Grid.Row="6" Grid.Column="1" Height="25" />
                                <TextBox x:Name="TxtProjectName" Margin="0 0 8 0" Text="{Binding ElementName=LivCategories, Path = SelectedValue.ProjectName, Mode = TwoWay}" Grid.Row="6" Grid.Column="2" Height="25" />
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.