Results 1 to 5 of 5

Thread: [RESOLVED] [WPF] ComboBox refusing to select an item

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Resolved [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:
    1. <!-- Journal-->
    2.         <TextBlock Grid.Column="0" Grid.Row="3" Text="Journal:" />
    3.         <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:
    1. public partial class EditPaperWindow : Window, INotifyPropertyChanged
    2.     {
    3.         public EditPaperWindow(Paper paper)
    4.         {
    5.             InitializeComponent();
    6.             this.DataContext = this;
    7.            
    8.             this.LoadLists();
    9.             _Paper = paper ?? new Paper();
    10.         }
    11.  
    12.         private readonly Paper _Paper;
    13.         public Paper Paper { get { return _Paper; } }
    14.  
    15.         private EntityCollection<Journal> _Journals;
    16.         public EntityCollection<Journal> Journals { get { return _Journals; } }
    17.  
    18.         private void LoadLists()
    19.         {
    20.             _Authors = AuthorManager.Instance.Load();
    21.             _Journals = JournalManager.Instance.Load();
    22.             _Categories = CategoryManager.Instance.Load();
    23.         }
    24.     }
    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:
    1. public EditPaperWindow(Paper paper)
    2.         {
    3.             InitializeComponent();
    4.             this.DataContext = this;
    5.            
    6.             this.LoadLists();
    7.             _Paper = paper ?? new Paper();
    8.  
    9.             journalsCombo.SelectedItem = this.Paper.Journal;
    10.         }
    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.

  2. #2
    Frenzied Member Lightning's Avatar
    Join Date
    Oct 2002
    Location
    Eygelshoven
    Posts
    1,611

    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?
    VB6 & C# (WCF LINQ) mostly


    If you need help with a WPF/WCF question post in the NEW WPF & WCF forum and we will try help the best we can

    My site

    My blog, couding troubles and solutions

    Free online tools

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WPF] ComboBox refusing to select an item

    Quote Originally Posted by Lightning View Post
    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.

    Quote Originally Posted by Lightning View Post
    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:
    1. /// <summary>
    2.     /// Represents a single Paper in the database table Papers.
    3.     /// </summary>
    4.     public partial class Paper : Entity
    5.     {  
    6.         public Paper()
    7.         {
    8.             _Authors = new EntityCollection< Author >();
    9.             _Categories = new EntityCollection< Category >();
    10.             PdfFilePath = "";
    11.             Title = "";
    12.             Year = 0;
    13.             Volume = 0;
    14.             PagesFrom = 0;
    15.             PagesTo = 0;
    16.  
    17.             this.Constructor();
    18.         }
    19.        
    20.         /// <summary>
    21.         /// Called after the constructor is completed and all default property values are set.
    22.         /// </summary>
    23.         partial void Constructor();
    24.        
    25.         private string _PdfFilePath;
    26.         public string PdfFilePath
    27.         {
    28.             get { return _PdfFilePath; }
    29.             set
    30.             {
    31.                 _PdfFilePath = value;
    32.                 this.OnPropertyChanged("PdfFilePath");
    33.                 this.OnPdfFilePathChanged();
    34.             }
    35.         }
    36.         private string _Title;
    37.         public string Title
    38.         {
    39.             get { return _Title; }
    40.             set
    41.             {
    42.                 _Title = value;
    43.                 this.OnPropertyChanged("Title");
    44.                 this.OnTitleChanged();
    45.             }
    46.         }
    47.         private int _Year;
    48.         public int Year
    49.         {
    50.             get { return _Year; }
    51.             set
    52.             {
    53.                 _Year = value;
    54.                 this.OnPropertyChanged("Year");
    55.                 this.OnYearChanged();
    56.             }
    57.         }
    58.         private int _Volume;
    59.         public int Volume
    60.         {
    61.             get { return _Volume; }
    62.             set
    63.             {
    64.                 _Volume = value;
    65.                 this.OnPropertyChanged("Volume");
    66.                 this.OnVolumeChanged();
    67.             }
    68.         }
    69.         private int _PagesFrom;
    70.         public int PagesFrom
    71.         {
    72.             get { return _PagesFrom; }
    73.             set
    74.             {
    75.                 _PagesFrom = value;
    76.                 this.OnPropertyChanged("PagesFrom");
    77.                 this.OnPagesFromChanged();
    78.             }
    79.         }
    80.         private int _PagesTo;
    81.         public int PagesTo
    82.         {
    83.             get { return _PagesTo; }
    84.             set
    85.             {
    86.                 _PagesTo = value;
    87.                 this.OnPropertyChanged("PagesTo");
    88.                 this.OnPagesToChanged();
    89.             }
    90.         }
    91.  
    92.    
    93.         private Journal _Journal;
    94.         public Journal Journal
    95.         {
    96.             get { return _Journal; }
    97.             set
    98.             {
    99.                 _Journal = value;
    100.                 this.OnPropertyChanged("Journal");
    101.                 this.OnJournalChanged();
    102.             }
    103.         }
    104.        
    105.         public int JournalId
    106.         {
    107.             get { return (this.Journal != null ? this.Journal.Id : 0); }
    108.         }
    109. }
    By creating another partial Paper class I can monitor when the OnJournalChanged method is called, which is what I did:
    csharp Code:
    1. public partial class Paper
    2.     {        
    3.         partial void OnJournalChanged()
    4.         {
    5.             Debug.WriteLine("Journal changed.");
    6.         }
    7.     }
    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...

  4. #4
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    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.

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [WPF] ComboBox refusing to select an item

    Quote Originally Posted by Evil_Giraffe View Post
    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
  •  



Click Here to Expand Forum to Full Width