|
-
Jun 21st, 2011, 12:14 PM
#1
[RESOLVED] [WPF] ComboBox refusing to select an item
Hi,
I am creating a simple application for my own use that keeps track of scientific papers I have. Basically it just displays a list of papers, where each paper has properties like the title, the authors, any categories, the journal, the volume, pages, and the pdf file path.
I have a window EditPaperWindow that displays these properties for one paper and allows me to edit them (or create a new paper). The issue is the Journal. There is a ComboBox bound to an ObservableCollection<Journal> (which I fill in the constructor of the window). When the window loads, it should simply display the selected journal for that paper.
Saving a paper works just fine, I can select a journal from the combobox and it will be saved to the database. When I re-load that paper immediately after however (or any other time for that matter) the selected journal does not appear in the ComboBox.
There is one catch that may or may not be related to the problem, which is that the ComboBox is editable (IsEditable = True), so that if I want to create a new journal I can simply type the name of the journal and before saving the paper it will then save that journal to the database. This way I don't have to go to a separate 'journal editing' window to add a new journal before I create a new paper.
I have tried everything I could think of to get the combobox to display the journal, nothing works.
The first thing I tried is the way I'm used to in WPF, simply using databinding. I have already found that the SelectedItem property should go before the ItemsSource property in the XAML, but I already had that:
xml Code:
<!-- Journal--> <TextBlock Grid.Column="0" Grid.Row="3" Text="Journal:" /> <ComboBox Grid.Column="1" Grid.Row="3" IsEditable="True" SelectedItem="{Binding Path=Paper.Journal, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Path=Journals}" x:Name="journalsCombo" DisplayMemberPath="Name" />
In the code-behind for the window, I have this:
csharp Code:
public partial class EditPaperWindow : Window, INotifyPropertyChanged { public EditPaperWindow(Paper paper) { InitializeComponent(); this.DataContext = this; this.LoadLists(); _Paper = paper ?? new Paper(); } private readonly Paper _Paper; public Paper Paper { get { return _Paper; } } private EntityCollection<Journal> _Journals; public EntityCollection<Journal> Journals { get { return _Journals; } } private void LoadLists() { _Authors = AuthorManager.Instance.Load(); _Journals = JournalManager.Instance.Load(); _Categories = CategoryManager.Instance.Load(); } }
JournalManager is a autogenerated class and its Load method loads all Journals from the database.
Journal is an object with properties Id and Name.
EntityCollection<T> inherits ObservableCollection<T>.
From simple debugging I've deduced that the journals are loaded from the database correctly and the Paper.Journal property is the correct journal object. The ComboBox simply refuses to display it and stays blank (when I use the dropdown, it displays all journals correctly).
The next thing I tried is to get rid of the bound SelectedItem and just do it in code, so I've modified the constructor to:
csharp Code:
public EditPaperWindow(Paper paper) { InitializeComponent(); this.DataContext = this; this.LoadLists(); _Paper = paper ?? new Paper(); journalsCombo.SelectedItem = this.Paper.Journal; }
Nothing. From debugging again I can see that Paper.Journal is correct. Immediately after assigning the SelectedItem though, journalsCombo.SelectedItem is still null! It seems like it completely ignores the assignment...
I've tried various other approaches, such as using SelectedValue, setting the SelectedIndex, but nothing works, the ComboBox remains empty.
I'm at a loss here; shouldn't both of these approaches work just fine? Why is the ComboBox ignoring the SelectedItem assignment?
Thanks for any help.
-
Jun 21st, 2011, 02:40 PM
#2
Re: [WPF] ComboBox refusing to select an item
You could try to raise the propertychanged event in the constructor to see if that helps (it is no sollution but is might help you find the problem).
Does the property change if you select a value in the combobox?
-
Jun 21st, 2011, 03:16 PM
#3
Re: [WPF] ComboBox refusing to select an item
 Originally Posted by Lightning
You could try to raise the propertychanged event in the constructor to see if that helps (it is no sollution but is might help you find the problem).
You mean the property changed event of the Paper.Journal property (perhaps the entire Paper property)? I can try that... but it doesn't work even if I explicitly assign the SelectedItem, so I don't see why that should change anything.
 Originally Posted by Lightning
Does the property change if you select a value in the combobox?
Yes, the Paper.Journal property changes. The code for all this is autogenerated by my database code generator and includes a partial method for every property which is called when it changes. In detail:
csharp Code:
/// <summary>
/// Represents a single Paper in the database table Papers.
/// </summary>
public partial class Paper : Entity
{
public Paper()
{
_Authors = new EntityCollection< Author >();
_Categories = new EntityCollection< Category >();
PdfFilePath = "";
Title = "";
Year = 0;
Volume = 0;
PagesFrom = 0;
PagesTo = 0;
this.Constructor();
}
/// <summary>
/// Called after the constructor is completed and all default property values are set.
/// </summary>
partial void Constructor();
private string _PdfFilePath;
public string PdfFilePath
{
get { return _PdfFilePath; }
set
{
_PdfFilePath = value;
this.OnPropertyChanged("PdfFilePath");
this.OnPdfFilePathChanged();
}
}
private string _Title;
public string Title
{
get { return _Title; }
set
{
_Title = value;
this.OnPropertyChanged("Title");
this.OnTitleChanged();
}
}
private int _Year;
public int Year
{
get { return _Year; }
set
{
_Year = value;
this.OnPropertyChanged("Year");
this.OnYearChanged();
}
}
private int _Volume;
public int Volume
{
get { return _Volume; }
set
{
_Volume = value;
this.OnPropertyChanged("Volume");
this.OnVolumeChanged();
}
}
private int _PagesFrom;
public int PagesFrom
{
get { return _PagesFrom; }
set
{
_PagesFrom = value;
this.OnPropertyChanged("PagesFrom");
this.OnPagesFromChanged();
}
}
private int _PagesTo;
public int PagesTo
{
get { return _PagesTo; }
set
{
_PagesTo = value;
this.OnPropertyChanged("PagesTo");
this.OnPagesToChanged();
}
}
private Journal _Journal;
public Journal Journal
{
get { return _Journal; }
set
{
_Journal = value;
this.OnPropertyChanged("Journal");
this.OnJournalChanged();
}
}
public int JournalId
{
get { return (this.Journal != null ? this.Journal.Id : 0); }
}
}
By creating another partial Paper class I can monitor when the OnJournalChanged method is called, which is what I did:
csharp Code:
public partial class Paper
{
partial void OnJournalChanged()
{
Debug.WriteLine("Journal changed.");
}
}
The debug window shows the journal changes after I select a different one in the ComboBox. However, it also shows this about 5-10 times after I simply open the edit window. That might have to do with some other generated code (when the Paper is loaded from the database I can see how the Journal property might be set multiple times, perhaps a few times to null even), but I'm not sure if that might be related to the problem or not...
-
Jun 21st, 2011, 06:50 PM
#4
Re: [WPF] ComboBox refusing to select an item
Is the instance of Journal on the Paper instance the same instance as the one in the JournalManager? WPF probably wires it up based on reference equality.
-
Jun 22nd, 2011, 05:05 AM
#5
Re: [WPF] ComboBox refusing to select an item
 Originally Posted by Evil_Giraffe
Is the instance of Journal on the Paper instance the same instance as the one in the JournalManager? WPF probably wires it up based on reference equality.
Wow, can't believe I didn't think of that 
You are completely right. The Journals loaded into the ComboBox (JournalManager.Instance.Load) are of course different instances than the Journal property of the Paper I loaded (this Paper object has been loaded previously to fill the main grid of papers, I am merely passing the selected paper around).
I've let my base Entity class (the class that gives each database record its Id property) implement IEquatable<Entity> and override Equals(object) so that they are considered equal when their Ids are equal. It works fine now 
Thanks!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|