简体   繁体   中英

ComboBox in DataGrid: ItemSource bound to dynamic resource, how to set default row?

I'm working in a C# project [for school], using WPF and implementing MVP. In this code, I've got a DataGrid showing a list of divers. The first column is the Name, and the second column shall show 'DivingType'. DivingType is a built in object, which has a property ID, such as 103A. There are about 400 of these, stored in a list, and each Diver ('row') has a Dives ( List<Dive> ) Property, and each of these Dives has a divingType property.

What we want to have, is that this column will by default show the DivingType.ID associated with the diver, but that the dropdown list shall contain ALL diving types, such that you shall be able to change it from there [and update the diver object]. To further complicate it, this is one of many views which we add to our window as UserControls.

With that said, here is the code. I've tried to cut out unnecessary clutter which I'm certain has no impact on the result.

<Window ...>
    <Window.Resources>
        <local:Presenter x:Key="myPresenter"/>
    </Window.Resources>
    <DockPanel DataContext="{StaticResource myPresenter}">
        <UserControl ...>
            <DataGrid ItemsSource="{Binding DiverList}" x:Name="datagrid">
                    <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Width="1*" Binding="{Binding Name}"/>
                    <DataGridTemplateColumn Header="Diving type" Width="1*">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, 
                                                                Path=DataContext.DivingTypes}"
                                          DisplayMemberPath="ID"
                                          SelectedValue="{Binding Dives[0]}"
                                          SelectedValuePath="divingType">
                                </ComboBox>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </UserControl>
   </DockPanel>
</Window>

When the program runs I get all DivingTypes.ID inside the combobox, but no selected value. The code does not put any related errors into the output window. I believe that what happens is that it calls DivingType.Equals but passing the DataContext for the row (the Diver) instead of the SelectedValuePath which I specify. Any way to override this behaviour inside XAML? Or is there an easier way to achieve this?

EDIT: I've since edited the code posted above to be:

<ComboBox ItemsSource="{
                           Binding RelativeSource={
                               RelativeSource AncestorType=UserControl
                           }, 
                           Path=DataContext.DivingTypes
                       }"
          SelectedValue="{
                            Binding Dives[0].divingType, Mode=TwoWay
                         }"
/>

This makes the correct value show in the combobox at the start, DivingType.ID is loaded from the Diver.Dives[0].divingType, but it still does not set the property when I select a new value in the dropdown box.

Use UpdateSourceTrigger =PropertyChanged.

Explanation here .

Have you tried to implemented INotifyPropertyChanged in your viewmodel and then raise the PropertyChanged event when the SelectedValue gets set.

If this is not working, can you set the SelectedValue

SelectedValue="{Binding Path=divingType, Mode=TwoWay}"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM