locked
Combobox selected item binding RRS feed

  • Question

  • Hi,

    First of all, my apologies to make this my first post but this has been bugging me for a few days now and I want to end my sleepless nights and nightmares of xaml.

    My company asked me to make a small program to register data for internships. Since I don't have much experience with normal windows forms applications i wanted to make a asp.net application but my company insisted it wouldn't be a web page. Since you can run silverlight apps outside the browser and I wanted to learn silverlight I decided to take up silverlight and try it out.

    So here's the problem and cause of my sleepless nights!

    In my database i have to tables "Schools" and "Contacts".
    In the table Contacts there's a field SchoolID wich references the ID in Schools.

    In one of my pages i have a datagrid with all contacts. To add or edit a contact i wanted to use a childwindow with a dataform. In this childwindow there are all the fields from the contact. To make it more user friendly, I added a Combobox which should show a list of all the schools and have the right school selected. Problem is that the selected item in the combobox is always the first record and not the record it should be...

    code of the childwindow:

      <Grid x:Name="LayoutRoot" Margin="0" Width="auto">
            <!--main grid resources-->
            <Grid.Resources>
                <riaControls:DomainDataSource AutoLoad="True" d:DesignData="{d:DesignInstance my:School, CreateList=true}" Height="0" 
                            x:Key="ddsScholen" Name="SchoolDomainDataSource" QueryName="GetSchoolQuery" Width="0">
                    <riaControls:DomainDataSource.DomainContext>
                        <my:StageRegistratieContext />
                    </riaControls:DomainDataSource.DomainContext>
                </riaControls:DomainDataSource>  
            </Grid.Resources>
     
    
            <!--main content goes here! -->
            <toolkit:DataForm Name="frmEditContactpersoon" AutoGenerateFields="False" CommandButtonsVisibility="None">
                <toolkit:DataForm.EditTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <toolkit:DataField Label="Voornaam">
                                <TextBox  Height="23" Name="VoornaamTextBox" Text="{Binding Path=Voornaam, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}"  />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Naam">
                                <TextBox  Height="23" Name="NaamTextBox" Text="{Binding Path=Naam, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}"  />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Telefoon">
                                <TextBox  Height="23" Name="TelefoonTextBox" Text="{Binding Path=Telefoon, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}"  />
                            </toolkit:DataField>
                            <toolkit:DataField Label="Fax">
                                <TextBox  Height="23" Name="FaxTextBox" Text="{Binding Path=Fax, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}"  />
                            </toolkit:DataField>
                            <toolkit:DataField Label="E-mail">
                                <TextBox  Height="23" Name="EmailTextBox" Text="{Binding Path=Email, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}"  />
                            </toolkit:DataField>
                            <toolkit:DataField Label="School">
                               <ComboBox Height="23" Name="cmbScholen" Width="120"
                                    ItemsSource="{Binding Path=Data, Source={StaticResource ddsScholen}}"
                                    DisplayMemberPath="Naam"
                                    SelectedValuePath="ID"
                                    SelectedValue="{Binding Path=SchoolID}" >
            </ComboBox>
                            </toolkit:DataField>
                        </StackPanel>
                    </DataTemplate>
                </toolkit:DataForm.EditTemplate>
            </toolkit:DataForm>
    
    
            <!--OK CANCEL-->
            <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="350">
                <Button x:Name="OKButton" Content="OK" Width="75" Height="23" HorizontalAlignment="Right"  />
                <Button x:Name="CancelButton" Content="Cancel" Width="75" Height="23" HorizontalAlignment="Right"  />
                
            </StackPanel>
    
        </Grid>

    Depending on what i want to do (insert or edit) the constructor is different in the code behind:

    Partial Public Class EditContactpersoon
        Inherits ChildWindow
    
        Public Property ContactpersoonItem As Contactpersoon
        Public Property NieuweContactpersoon As Boolean
    
    
        Public Sub New()
            InitializeComponent()
            NieuweContactpersoon = True
            ContactpersoonItem = New Contactpersoon
            frmEditContactpersoon.CurrentItem = ContactpersoonItem
            frmEditContactpersoon.BeginEdit()
        End Sub
    
    
        Public Sub New(ByVal CurrentContactpersoonItem As Contactpersoon)
            'edit a contact
            InitializeComponent()
            NieuweContactpersoon = False
            ContactpersoonItem = CurrentContactpersoonItem
            frmEditContactpersoon.CurrentItem = ContactpersoonItem
            frmEditContactpersoon.BeginEdit()
        End Sub
    
        Public Sub New(ByVal SchoolItem As School)
            'use this to make contact for a selected school
            InitializeComponent()
            NieuweContactpersoon = True
            ContactpersoonItem = New Contactpersoon
            ContactpersoonItem.SchoolID = SchoolItem.ID
            frmEditContactpersoon.CurrentItem = ContactpersoonItem
            frmEditContactpersoon.BeginEdit()
        End Sub
    
        Public Sub New(ByVal SchoolID As Integer)
            'use this to make contact for a selected school
            InitializeComponent()
            NieuweContactpersoon = True
            ContactpersoonItem = New Contactpersoon
            ContactpersoonItem.SchoolID = SchoolID
            frmEditContactpersoon.CurrentItem = ContactpersoonItem
            frmEditContactpersoon.BeginEdit()
        End Sub

    Private Sub OKButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles OKButton.Click frmEditContactpersoon.CommitEdit() Me.DialogResult = True End Sub Private Sub CancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles CancelButton.Click ContactpersoonItem = Nothing frmEditContactpersoon.CancelEdit() Me.DialogResult = False End Sub
    ......
    End Class

    Is there a way to make this work? Any help would be greatly appreciated!!!

    edit: I kind of messed up the markup in the last part but still readable i hope...

    Monday, February 6, 2012 5:03 AM

Answers

  • Well, I don't use Ria or DataForms, but there are a couple of things I don't see in your code.  I don't see where you created the resource that is your ddScholen.  I also don't see where you set the DataContext of the form.

    But I would guess that you could create a property in the DataForm code behind that is the class of the Items in the Combobox ItemsSource.  Then in the Loaded event handler for the DataForm, you could set the DataContext of the Combobox to be the DataForm.  Then set the value of the SelectedItem to be the item in the list that you want.  As I said before, you could iterate the items in the list (in the resource) until you find the one you want selected.  Then set you SelectedItem property.  And don't forget to implement IPropertyChangedNotification so that the control will KNOW that you set it.  AND make the SelectedItem be bound with Mode=TwoWay.

    That is about all I can suggest.

    Can you say specifically what problem you are having? What part is not working and what part is?  Is the DataForm showing you some data from your Ria context?  Is that part hooked up and working?

    ... time passes ...

    Oh, I SEE your keyed resource for ddScholen.  So THAT looks like it should probably be doing the right thing.

    Monday, February 6, 2012 10:24 PM
  • Hi Gloin,

    It is not suggested to bind ComboBox's ItemsSource to DomainDataSource in your case and Kley explained this indetails in his blog.

    It is recommanded to load the school list from DomainContext in code and store it as a StaticResource. For details, please refer to another great post at

    http://weblogs.asp.net/manishdalal/archive/2009/07/03/silverlight-3-combobox-control.aspx

    Please let me know if you have any further questions.

    Best Regards,

    Wednesday, February 8, 2012 6:13 AM

All replies

  • Hello Gloin,

    You can use MVVM pattern

    In Model file :

    You can first create one Dictionary<int, string>. fetch data from school table and assign schoolId as a key and SchoolName as a value in the Dictionary.

    In View Model file :

    create one property for the Dictionary<int, string> and assign model file variable to this.

    and bind this property in View/XAML file to that combobox using Binding.

    Assign one more property of that combobox Display menber as value/String of that Dictionary.

    Your problem will be solved.

    Thanks

    Bhushan

    Monday, February 6, 2012 5:47 AM
  • You can use MVVM pattern

    I'd rather do this as a last resort as i'm not familiar with this pattern.

    I learned silverlight by watching some tutorial video's on this site and some other sites. My boss is getting rather impatient that it's taking this much time to make such a simple program. (he sure knows how to keep me motivated >_> )

    Is there any other method i can use to accomplish this?

    Thanks anyway for your reply bhushan!

    Monday, February 6, 2012 7:51 AM
  • Although I certainly know exactly what you mean about your boss, I can't imagine creating an app without it anymore.

    I put together a little skeleton for someone the other day.  Perhaps it will help you to go ahead and START using MVVM.  You don't have to convert everything right away, but you can do pieces as you have time.

    Here it is:

    http://social.msdn.microsoft.com/Forums/en-US/silverlightstart/thread/063cb48e-d9f8-4a71-9938-d43ae236f6a8//1?Silverlight+Business+Application+Template+Reference+xaml+from+ChildWindow+VB

    FWIW, you don't have to have a dictionary either.  I usually just use Lists of some Object Class.  You bind the ItemsSource to the List and the SelectedItem to a property in your class.  Then use DisplayMemberPath to tell it which part of the object to display.

    Monday, February 6, 2012 2:57 PM
  • Also, in your case, you have the ddsScholen as the list of school objects.  Assuming that each one has an ID property, just iterate through that list, find the object that matches the ID you want to have selected.  Then set the SelectedItem poperty in your code that is bound to the SelectedItem of the Combobox.  The Combobox will then have the right one selected.

    Don't forget property change notification.

    And I would get rid of the SelectedValuePath and SelectedValue  stuff.  I think it is more difficult to work with than just using the single SelectedItem.  Works just as well, but is simpler, imho.

    Monday, February 6, 2012 3:04 PM
  • I am certainly planning on finding out on how MVVM actually works and how to implement it but currently I don't realy have time for it. + the method of programming resembles more the method i used in asp.net. I want to get out an early beta version of the program so the basic data (nothing of actual importance) can be filled by administration personnel. This will get my boss of my back and give me some time to look in to this.

    Also, in your case, you have the ddsScholen as the list of school objects.  Assuming that each one has an ID property, just iterate through that list, find the object that matches the ID you want to have selected.  Then set the SelectedItem poperty in your code that is bound to the SelectedItem of the Combobox.  The Combobox will then have the right one selected.

    Asuming I can implement what you described above without MVVM: in what event should i change the SelectedItem of the combobox. When I look at the cmbScholen_Loaded event the combobox has no items in it... When am i sure that the itemsource of the combobox is bound and the combobox is filled with my school items?

    Anyway thanks for the help, it's much appreciated!

    Monday, February 6, 2012 5:54 PM
  • Well, I don't use Ria or DataForms, but there are a couple of things I don't see in your code.  I don't see where you created the resource that is your ddScholen.  I also don't see where you set the DataContext of the form.

    But I would guess that you could create a property in the DataForm code behind that is the class of the Items in the Combobox ItemsSource.  Then in the Loaded event handler for the DataForm, you could set the DataContext of the Combobox to be the DataForm.  Then set the value of the SelectedItem to be the item in the list that you want.  As I said before, you could iterate the items in the list (in the resource) until you find the one you want selected.  Then set you SelectedItem property.  And don't forget to implement IPropertyChangedNotification so that the control will KNOW that you set it.  AND make the SelectedItem be bound with Mode=TwoWay.

    That is about all I can suggest.

    Can you say specifically what problem you are having? What part is not working and what part is?  Is the DataForm showing you some data from your Ria context?  Is that part hooked up and working?

    ... time passes ...

    Oh, I SEE your keyed resource for ddScholen.  So THAT looks like it should probably be doing the right thing.

    Monday, February 6, 2012 10:24 PM
  • Hi Gloin,

    It is not suggested to bind ComboBox's ItemsSource to DomainDataSource in your case and Kley explained this indetails in his blog.

    It is recommanded to load the school list from DomainContext in code and store it as a StaticResource. For details, please refer to another great post at

    http://weblogs.asp.net/manishdalal/archive/2009/07/03/silverlight-3-combobox-control.aspx

    Please let me know if you have any further questions.

    Best Regards,

    Wednesday, February 8, 2012 6:13 AM
  • Hi, sorry for my late answer but I haven't found the time yesterday to test your suggestions. (my primary task isn't actualy programming, I'm lucky if I can have visual studio open for more than 1 hour without interruption.)

    In the constructor of the child window I pass a Contact Item which was selected from the parent page.
    Then I set the currentitem of the dataform to that contact item. The form is loaded and all textboxes are filled in correctly, even if I save it al goes back to the database. Even my combobox items are filled in. Only the selected item is always the first item. The SelectedItem or SelectedValue simply doesn't work.

    If I try to iterate through the comboboxitems in code behind to set the right selecteditem in but when I debug the items simply aren't there. Not in the cmbScholen_Loaded, cmbScholen_Loaded, SchoolDomainDataSource_Loaded,....

    allright as i was typing this i was debugging this over and over again but now i found that the items are there in the SchoolDomainDataSource_LoadedData event! so there I can iterate through the items and set the selected item. So for now, all is well!

    I can't thank you enough for the help and hints

    edit: @Shi_Ding: Apparently I was posting the above when you posted your reply but I found alot of forum posts and blogs about this problem with the combobox but almost all of them suggest using MVVM or a custom combobox or something. I didn't see that blog post and solution yet so I'll give it a try.

    Thanks for the help guys.

    Wednesday, February 8, 2012 8:20 AM
  • Sorry for the double post but I thought it'd be appropriate to giving this an update. But I got the combobox working! I simply had to look in the loaded data event of the domain data source of the combobox and then manually iterate through the itmes and selecting the corect one. Don't know why I overlooked this while debugging though...

    Unfortunately I bumped into some other problems (not related to this one) and I can't afford to waste this much time on such a simple program... So before my boss goes into an all caps rage, I've placed my silverlight project on the shelf and I've restarted in ASP.NET until I can convince him to send me on a silverlight course.

    I'll mark the posts of mtiede and Shi Ding as answers as they most probably do solve this issue and helped me find the answer...

    Anyway thanks again for the help.

    Friday, February 10, 2012 5:28 AM
  • What was the other problem?

    Friday, February 10, 2012 11:03 AM