question

Anja-7727 avatar image
0 Votes"
Anja-7727 asked Anja-7727 commented

Selected Item in ComboBox wpf with Binding

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-wpf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered Anja-7727 commented

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



x.gif (156.5 KiB)
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you so much. I'm a very happy woman right now. I have tried so many things without success. Yours work like a charm :-)

0 Votes 0 ·
DaisyTian-1203 avatar image
0 Votes"
DaisyTian-1203 answered

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.gif (68.5 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Anja-7727 avatar image
0 Votes"
Anja-7727 answered

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" />
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.