WPF Combobox not updating ViewModel
I have a really weird issue with Combobox in WPF. I have used it before in a simpler implementation and thought I knew how it works, but apparently not. The scenario is as follows... I have three classes which are in a parent/child relationship, I have a list of a type AnswerViewModel which I populate in a Combobox. I want the IsSelected property on the class to be the value that is get/set in the Combobox. Below is some of the code, hopefully enough to see what I am referring to.
These are the models.
public class Quiz
{
public string QuizName {get;set;}
public List<Question> Questions {get;set;}
}
public class Question
{
public int QuestionId {get;set;}
public string QuestionText {get;set;}
public List<Answer> {get;set;}
}
public class Answer
{
public int AnswerId {get;set;}
public string AnswerText {get;set;}
public bool IsSelected {get;set;}
}
These are the ViewModels
QuizViewModel.cs
// This will create QuestionViewModel for each question.
ObservableCollection<QuestionViewModel> Questions {get;set;}
QuestionViewModel.cs
// This will create AnswerViewModel for each answer
ObservableCollection<AnswerViewModel> Answers {get;set;}
AnswerViewModel.cs
Answer answer;
// ctor
public AnswerViewModel(Answer answer...)
{
this.answer = answer;
...
}
public string AnswerText
{
get { return answer.AnswerText; }
set
{
answer.AnswerText = value;
NotifyPropertyChanged("AnswerText");
}
}
public bool IsSelected
{
get { return _answer.IsSelected; }
set
{
answer.IsSelected = value;
NotifyPropertyChanged("IsSelected"); // <--- Breakpoint
}
}
These are the XAMLs
Quiz.xaml
<ItemsControl ItemsSource="{Binding Questions}" />
Question.xaml
<ComboBox x:Name="answerCombo"
ItemsSource="{Binding Answers}"
DisplayMemberPath="AnswerText"
SelectedValue="{Binding Path=IsSelected}"
SelectedValuePath="IsSelected"/>
The Combobox is populated correctly (It is bound to the Collection of AnswerViewModel), but when I make a selection what I expect is to see at the breakpoint is two events. One for the false on the item no longer selected, and true for the new item selected. But instead it never gets hit.
So I scour the web looking for help and found some interesting information and tried a number of thi开发者_如何学Gongs but, so far nothing seems to be complete. For example:
<ComboBox x:Name="answerCombo"
ItemsSource="{Binding Answers}"
DisplayMemberPath="AnswerText"
SelectedValue="{Binding Path=IsSelected}"
SelectedValuePath="IsSelected">
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
</Style>
</ComboBox.ItemContainerStyle>
</Combobox>
But this only selects the correct item in the Combobox when drop-down. Which I understand is correct for this markup.
So, in short, I would like to have the IsSelected Property on the AnswerViewModel updated when I select an item in the Combobox. Any help would be greatly appreciated.
If more information is required just let me know.
Thank you, Obscured
** Update **
Ok, I think I actually resolved it, but still If anyone has suggestions, or thoughts on this, I would still like to hear them.
Here is what I did, I only changed the Combobox xaml as follows:
<ComboBox x:Name="answerCombo"
ItemsSource="{Binding Answers}"
DisplayMemberPath="AnswerText"
SelectedValue="{Binding Path=ItemsSource/, RelativeSource={RelativeSource Self}}">
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
</Style>
</ComboBox.ItemContainerStyle>
</Combobox>
Basically this sets the selectedvalue to the current item, and since the itemcontainerstyle handles the case when drop-down it binds the IsSelected property of the combobox to the IsSelected property of my ViewModel. And this appears to do the trick.
Just remove the SelectedValue
and SelectedValuePath
properties, it's not how they work. SelectedValuePath
indicates which property of the selected item will be the SelectedValue
of the ComboBox
; if you say that the SelectedValuePath
is "IsSelected", the SelectedValue
will be SelectedItem.IsSelected
, which is clearly not what you want... And your binding for SelectedValue
refers to a property that doesn't exist (QuestionViewModel.IsSelected
)
This should work for you:
<ComboBox x:Name="answerCombo"
ItemsSource="{Binding Answers}"
DisplayMemberPath="AnswerText">
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
</Style>
</ComboBox.ItemContainerStyle>
</Combobox>
have you try:
<ComboBox x:Name="answerCombo"
ItemsSource="{Binding Answers}"
DisplayMemberPath="AnswerText"
SelectedValue="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="IsSelected"/>
精彩评论