Need to use SelectedItem instead of SelectedValue in a WPF ComboBox

Rod At Work 866 Reputation points
2021-03-29T22:02:25.787+00:00

Back in December 2020 I asked The SelectedValue property is never assigned. I don't know what I'm doing wrong. At the time @DaisyTian-MSFT gave me an excellent solution. However, in this case I need to use the SelectedItem property of the ComboBox instead of the SelectedValue property. Back in December I had code in my ViewModel:

public long? InstrumentModelID   
{   
	get   
	{  
		if (Course != null)  
		{  
			return Course.InstrumentModelID;  
		}  
		return -1;  
	}  
	set  
	{  
		Course.InstrumentModelID = value;  
		RaisePropertyChanged();  
	}  
}  

That worked well and I could use the Watermark in the WPF ComboBox where I bound InstrumentModelID to the SelectedValue property of the ComboBox. But like I said, this go around I want to use the SelectedItem property. And at least in my experience I've found that having both the SelectedValue property and the SelectedItem property assigned in a ComboBox was a sure way of messing things up. I've avoided using SelectedValue and SelectedItem in the same ComboBox ever since. Here's what I've got so far in my view:

<ComboBox VerticalAlignment="Bottom"  
		  IsSynchronizedWithCurrentItem="True"  
		  SelectedItem="{Binding SelectedCourse, Mode=TwoWay}"  
		  ItemsSource="{Binding ActiveCourses}"  
		  Visibility="{Binding ShowDropDown}">  
	<i:Interaction.Behaviors>  
		<common:WatermarkBehavior Text="Select..." />  
	</i:Interaction.Behaviors>  
	<ComboBox.ItemTemplate>  
		<DataTemplate>  
			<Grid Margin="0,0,0,4">  
				<Grid.RowDefinitions>  
					<RowDefinition Height="Auto" />  
					<RowDefinition Height="Auto" />  
					<RowDefinition Height="Auto" />  
				</Grid.RowDefinitions>  
				<Grid.ColumnDefinitions>  
					<ColumnDefinition Width="125" />  
					<ColumnDefinition Width="*" />  
				</Grid.ColumnDefinitions>  
				<!-- left column -->  
				<TextBlock HorizontalAlignment="Right"  
						   FontWeight="Bold"  
						   Text="Instrument:" />  
				<TextBlock HorizontalAlignment="Right"  
						   Grid.Row="1"  
						   FontWeight="Bold"  
						   Text="Certification Type:" />  
				<TextBlock HorizontalAlignment="Right"  
						   Grid.Row="2"  
						   FontWeight="Bold"  
						   Text="Full/Recert:" />  
				<!-- right column -->  
				<TextBlock Margin="5,0,0,0"  
						   Grid.Column="1"  
						   Text="{Binding InstrumentModel.Model}" />  
				<TextBlock Margin="5,0,0,0"  
						   Grid.Row="1"  
						   Grid.Column="1"  
						   Text="{Binding CertificationType.CertType}" />  
				<TextBlock Margin="5,0,0,0"  
						   Grid.Row="2"  
						   Grid.Column="1"  
						   Text="{Binding CertificationLevel.CertLevel}" />  
			</Grid>  
		</DataTemplate>  
	</ComboBox.ItemTemplate>  
</ComboBox>  

I would have thought that if the SelectedCourse property defined in my ViewModel were null, that it would display the watermark. But that doesn't seem to be the case. It always displays the first element in the ActiveCourses collection - not what I want. (Of course, once the user selects and saves a course, then I expect that course to be displayed when returning to this view.)

So, is it a lack of understanding on my part? Or have I done something wrong here?

Developer technologies Windows Presentation Foundation
0 comments No comments
{count} votes

Accepted answer
  1. DaisyTian-1203 11,646 Reputation points
    2021-03-31T03:06:18.06+00:00

    You can show the Watermark by adding Load event for your ComboBox and adding its code like below when the selection is null:

     private void myCom_Loaded(object sender, RoutedEventArgs e)  
            {  
                myCom.SelectedIndex = -1;  
            }  
    

    I tested your code in three ways:
    One: I did a test project and reproduced your error with setting SelectedItem="{Binding SelectedCourse, Mode=TwoWay}" for the ComboBox, but when I deleted SelectedItem="{Binding SelectedCourse, Mode=TwoWay}" and not using SelectedValue for the ComboBox like below, the issue still existed.

     <ComboBox VerticalAlignment="Center"   
                      IsSynchronizedWithCurrentItem="True"   
                      ItemsSource="{Binding ActiveCourses}"   
                      >  
    

    Two: Then I tried to add SelectedValue and not use SelectedItem="{Binding SelectedCourse, Mode=TwoWay}" like below, the is also existed.

       <ComboBox VerticalAlignment="Center"   
                      IsSynchronizedWithCurrentItem="True"   
                      ItemsSource="{Binding ActiveCourses}"  
                      SelectedValue="Model1"  
                      SelectedValuePath="Model"  
                       
                      >  
    

    Three: Finally I tried to use binding to SelectedValue, it can show Watermark but with binding error , like below oicture shown:
    83081-capture.png

    It is inferred from the test results that the cause of this problem should be that you created the DataTemplate for the ComboBox.If I misunderstand your question, please point out.


    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 people found this answer helpful.
    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Rod Falanga 591 Reputation points
    2021-03-31T01:38:34.263+00:00

    I found a way of getting around it. Instead of using SelectedValue, I'm going to use SelectedIndex. That way I can define a property in the viewmodel, that I'll bind to the SelectedIndex of the ComboBox. I just need a way of assigning it a value of -1, when working with a new record. Before it was showing the user the first item in a collection, which I didn't want it to do.

    1 person found this answer helpful.
    0 comments No comments

  2. Viorel 122.5K Reputation points
    2021-03-30T05:54:55.483+00:00

    Maybe remove IsSynchronizedWithCurrentItem="True" if it is not needed for your kind of ActiveCourses collection.


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.