none
EF4 and WPF data binding - many to many relationship RRS feed

  • Question

  • Thanks in advance.

    Without boring you to death with all the details - I have an EF model intended to track project requests. The hierarchy is that corporate divisions have departments; the departments submit project requests. The requests have to be categorized by risk and can fall into one or more categories. This last component is represented in the database via a Many-to-Many table incorporating the RequestIDs and the RiskIDs. EF eliminates the many-to-many table and shows the association between the Request and RiskCategory entities.

    I've created a WPF form that ALMOST works they way I want, showing the users the details of their requests. I'd like to add to the form a combobox within a listview, from which the users can select the categories that apply to a given request. Only the combobox will be in the ListView

    So..the CollectionViewSource for the RiskCategories table is categoriesViewSource, and the CollectionViewSource for the RequestItems is named
    RequestItemsRiskCategoriesViewSource

    The Datacontext of the ListView itself is set to RequestItemsRiskCategoriesViewSource, and the combobox's ItemsSource is set to the categoriesViewSource. Try as I might, I can only get the combox to display the available RiskCategories, not the ones already assigned to the current RequestItem. If there is one category assigned, then one combobox hows in the listview. If 3, then 3 comboxes appear. But each one displays the first category in the list, not the assigned categories.

    Changing the datatemplate to a Textbox bound to Category works just fine, but gives the user no way to choose a valid value

    Here's the XAML that doesn't work

                <ListView.View>
                  <GridView>
                    <GridViewColumn x:Name="categoryColumn" Header="Category" Width="80">
                      <GridViewColumn.CellTemplate>
                        <DataTemplate>
                          <ComboBox
                            ItemsSource="{Binding Source={StaticResource categoriesViewSource}}"
                            SelectedValue="{Binding Path=RiskCategory}"                         DisplayMemberPath="Category">
                                                  </ComboBox>
                        </DataTemplate>
                      </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                  </GridView>
                </ListView.View>
    
    

    So...how do I get this comobox to work?

    Monday, December 6, 2010 4:00 PM

All replies

  • Hi Duke,

    Thanks for your post!

    Based on your discription, I think the issue is that ComboBox cannot pick up the correct assigned category as its selected item. Please let me know if I misunderstood your issue.

    ComboBox will call Object.Equals method to determine its selected item. So the assigned category won't be picked from the ComboBox's ItemsSource unless it "equals" to one of the items.

    I made a simple sample to illustrate this issue.

    <Window x:Class="Sample.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Sample"
        Title="MainWindow" Height="350" Width="525">
      <StackPanel>
        <ComboBox SelectedValue="{Binding MyProperty}" DisplayMemberPath="Name" Name="list"/>
      </StackPanel>
    </Window>
    
    namespace Sample
    {
      public partial class MainWindow : Window
      {
        public MyClass MyProperty { get; set; }
    
        public MainWindow()
        {
          InitializeComponent();
    
          list.ItemsSource = new List<MyClass>()
          {
            new MyClass(){Name="A"},
            new MyClass(){Name="B"},
            new MyClass(){Name="C"}
          };
          MyProperty = new MyClass() { Name = "C" };
          DataContext = this;
        }
      }
    
    
      public class MyClass
      {
        public string Name { get; set; }
      }
    }
    

    In the above sample, the ComboBox won't pick C as its current value. We can override Object.Equals method to fix this.

      public class MyClass
      {
        public string Name { get; set; }
    
        public override bool Equals(object obj)
        {
          MyClass other = obj as MyClass;
          if (other != null && other.Name == this.Name)
          {
            return true;
          }
          return false;
        }
    
        public override int GetHashCode()
        {
          return Name.GetHashCode();
        }
      }
    

    Hope this helps.

    If the problem presists, please feel free to let me know.

    Best regards,

    Min

    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact
    msdnmg@microsoft.com.


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread. Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to Microsoft All-In-One Code Framework to download or request code samples from Microsoft Community Team!
    Tuesday, December 7, 2010 7:41 AM
    Moderator
  • You may have given me some insight into why it ISN'T working. The combobox I'm trying to make work would show one side of a MANY TO MANY relationship, represented in the database by a mapping table.  EF removes the mapping table from the model and shows a direct relationship between the two tables. 

    You descibe the Object.Equals method, but what object(s) is it acting upon?  The only linkage is the primary key for each of the 'many' tables.  So how can the Object.Equals method possible succeed?

    So..I come back to the original question - does a many-to-many relationship require some special handling?

    Tuesday, December 7, 2010 4:59 PM
  • Hi Duke,

    I am currently looking into this issue and will give you an update as soon as possible.

    Thank you for your understanding and support.

    Best regards,

    Min

    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact
    msdnmg@microsoft.com.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to Microsoft All-In-One Code Framework to download or request code samples from Microsoft Community Team!
    Thursday, December 9, 2010 9:46 AM
    Moderator
  • Hi Duke Carey,

    I have created a such project today and now I have a better understanding of this problem.

    First of all, we need to set IsSynchronizedWithCurrentItem property of that ComboBox property. I would like to quote the documentation to explain this issue:

    "true if the SelectedItem is always synchronized with the current item in the ItemCollection; false if the SelectedItem is never synchronized with the current item; null if the SelectedItem is synchronized with the current item only if the Selector uses a CollectionView. The default value is null."

    If we don't set this property to false, all ComboBox will sync their SelectedItem with the current item of the CollectionView. This explains why all ComboBox display the first category in the list instead of the assigned categories.

    Then, if the type of RiskCategory you bind to SelectedValue and the categoriesViewSource items is a value type, the ComboBox should be able to pick up the correct item as the selected item.

    If it's not a value type, we need to override the Object.Equals method for that type. In my last post, I was thinking you bind SelectedValue to a RiskCategories object, and this class is derived from EntityObject and is auto-generated by the entityframework. If that's true, you can override the Equals method of that class to help the ComboBox to pick up the selecteditem.

    However, after we fixing all these things, the bindings' on the ComboBox will be limited to OneWay in both above approaches. As far as I know, we cannot use TwoWay bindings to update the changes back to the RelationshipTable. So I think YES, we need some special handling to update the changes of the many-to-many relationship back to the database.

    Since I am not quite familiar with EntityFramework, I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.

    Thank you for your understanding and support.

    Best regards,

    Min


    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, December 10, 2010 8:54 AM
    Moderator
  • Using many to many with EntityFramework and wanting to push two way bindings from WPF back into the entities. I don't see anything explicitly documented about this, and trying to work this out in a sample will be fairly involved.

     

    We have to write a full-fledged sample from start, this would likely get timely.

    My recommendation would be to have you open a support incident with Microsoft support, and see if we can't get a repro they can debug. You may have a few differant options for opening said support incident.

     

    Alliance and Premier VSIP membership includes a complimentary MSDN subscription, which includes 4 professional support incidents. These can be used to initialize a support request with Microsoft's Customer Support Services. Some versions of Visual Studio include a number of free support incidents as well. See the "Technical Support Incidents" topic for details.

     

    Your issue falls into a category that we are not able to resolve using the forums. There are various support options such as advisory and per issue. Please visit the below link to see the various paid support options that are available to better meet your needs. http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone


    bill boyce
    Friday, December 10, 2010 11:17 PM
  • Bill and Min -

    Thanks for your attention to this issue.  I'll monkey around to see if there is a simple sample I can post, just to simplify undertanding of the problem.  It really seems that this isn't an extraordinary use case that EF (and WPF) ought to handle.

    Saturday, December 11, 2010 1:58 AM
  • I'm having the same issue , Did any one able to adress this?

    How can i update the database via user selection? i need to update the MANY TO MANY table.


    Coder
    Wednesday, August 3, 2011 12:30 PM
  • @ Min Zhu

    i have the same problem (student , class), is there a fix for this using dataGird binding ?

    or we have to do special coding for this ?

    Saturday, June 15, 2013 8:24 PM