3

i've been through tons of attempts and forum posts but i still can't solve my issue.

ISSUE A combobox displaying data from an entity framework dbcontext does not display the selected value but DOES work for the item list. The selected item just shows

System.Data.Entity.DynamicProxies.Equipment_37EBC79AEAECCCCD132FD15F1C9172DF4DD402B322A9C5762AE640F03887F702

BUT the list of the combobox displays correctly....

SETUP I have a dbcontext that contains a class named equipment. Equipment has two items i want to display String Tag; Location.Name;

Selected Item Busted, List Works

  <ComboBox x:Name="cbxCopyTo" Grid.Row="2" Grid.Column="1"
                          IsEditable="True" IsTextSearchEnabled="True" IsTextSearchCaseSensitive="False"
                          ItemsSource="{Binding}">
                    <ComboBox.SelectedValue>
                        <DataTemplate>
                            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" >
                                <TextBlock.Text>
                                    <MultiBinding StringFormat="{}{0} ({1})">
                                        <Binding Path="Tag" />
                                        <Binding Path="Location.Name" />
                                    </MultiBinding>
                                </TextBlock.Text>
                            </TextBlock>
                        </DataTemplate>
                    </ComboBox.SelectedValue>
                    <ComboBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" >
                                <TextBlock.Text>
                                    <MultiBinding StringFormat="{}{0} ({1})">
                                        <Binding Path="Tag" />
                                        <Binding Path="Location.Name" />
                                    </MultiBinding>
                                </TextBlock.Text>
                            </TextBlock>
                        </DataTemplate>
                    </ComboBox.ItemTemplate>
                </ComboBox>

You can see above i even tried explicitly setting the selected value; but it didn't work. I did notice when i tried using a converter that it was never called for SelectedItem or SelectedValue when i put converters in there.

The below works if i ignore location (got from datasource drag and drop). This show both the list and selected item correctly.

<Label Grid.Row="1" Grid.Column="0" Content="Copy From:" />
                <ComboBox x:Name="cbxCopyTo" Grid.Row="1" Grid.Column="1"
                          IsEditable="True" IsTextSearchEnabled="True" IsTextSearchCaseSensitive="False"
                          DisplayMemberPath="Tag" ItemsSource="{Binding}">
                    <ComboBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <VirtualizingStackPanel/>
                        </ItemsPanelTemplate>
                    </ComboBox.ItemsPanel>
                </ComboBox>

Please help; i would be greatly appreciated!

Asvaldr
  • 197
  • 3
  • 15

3 Answers3

4

SOLVED - FOR OTHERS INFO

Ok i figured out way to make a concatenated property (like @Andy suggested) BUT without it appearing in the database.

By using code first annotations you can declare a property on the EF model that doesn't get mapped to the database but can be queried or binded like any db property. This is done in the declaration of your EF model class, like below:

/// <summary>
        /// Creates concatenation object that will not be mapped in the database but will be in the
        /// Object Relational Mapping (ORM) of the EF model.
        /// </summary>
        [NotMapped]
        public string TagAndLocation { get { return Tag + " (" + Location.Name + ")"; } } 

This then allows me to use the simple binding to "TagAndLocation" with the below XAML:

        <ComboBox x:Name="cbxCopyTo" Grid.Row="2" Grid.Column="1"
                  IsEditable="True" IsTextSearchEnabled="True" IsTextSearchCaseSensitive="False"
                  DisplayMemberPath="TagAndLocation" ItemsSource="{Binding}">
            <ComboBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel/>
                </ItemsPanelTemplate>
            </ComboBox.ItemsPanel>
        </ComboBox>

Thanks again to @Andy and @aguedo valdes for taking the time to make suggestions.

Asvaldr
  • 197
  • 3
  • 15
2

One difference between your two code samples is that in the second one, it sets ComboBox.DisplayMemberPath to something.

I believe that if this isn't set, the ComboBox will just call ToString() on the selected item. This would explain the value you're getting in your actual ComboBox.

DisplayMemberPath is just a string and expects a binding path, so you can't give it a multibinding unfortunately. I've never used the entity framework, but would it be possible to either override ToString() for the object you get back, or to add a property that contains the value you want and then use that for the value of DisplayMemberPath?

Andy
  • 30,088
  • 6
  • 78
  • 89
  • Thanks @Andy, i appreciate your answer. That option using different member is my fall back; but due to other factors i'd prefer the database not to have that in it. Also for my learning to as this is just where i'm scratching the surface on this binding stuff. If anyone does have another solution i'd love to hear it. – Asvaldr Aug 06 '13 at 03:33
1

If you are using entity framework code first check if your missing some virtual property in the model. Something like:

public class Equipment{
    ....
    public virtual Location Location {get; set;}
    ....
}
  • Thanks for the answer. I do have that. I works perfectly for all items displayed in the combobox drop down... just not for the selected item..... – Asvaldr Aug 06 '13 at 04:41