WPF Data Binding ComboBox in DataGridTemplateColumn - wpf

I have a DataGrid and I want to populate a column that contains a ComboBox with a dynamic ItemsSource of elements, based on the row. I have the combo box display correctly, and the correct list of elements are populated in the list, as pulled in from the AvailableLogFileProcessTypes property, which is a ReadOnlyCollection. However, when the selection is made by the user in the combobox, the LogFileProcessType property is not set to the selection.
Data:
Property LogFileDirectories, IEnumerable<LogFileData>,
LogFileData:
public LogFileProcessType LogFileProcessType{get;set;}
public ReadOnlyCollection<LogFileProcessType> AvailableLogFileProcessTypes { get; set; }
The property currently has a backing field, and the breakpoint in the set property does not get hit, so I know it is localized to the binding setup. What is wrong with my XAML that is preventing the property from being set?
As you can see, I've tried setting both the SelectedValue and SelectedItem in the CellEditingTemplate and the CellTemplate. I am not sure which of these is appropriate.
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=LogFileDirectories, UpdateSourceTrigger=PropertyChanged}"
HeadersVisibility="Column" CanUserReorderColumns="False" CanUserAddRows="False" Margin="0,0,0,35" Grid.RowSpan="3">
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Processed" Binding="{Binding Path=IsProcessingComplete, Mode=OneWay}" Width="70" IsReadOnly="True" />
<DataGridTemplateColumn Header="template">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding Path=LogFileProcessType, Mode=TwoWay}"
SelectedItem="{Binding Path=LogFileProcessType, Mode=TwoWay}"
ItemsSource="{Binding Path=AvailableLogFileProcessTypes}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding Path=LogFileProcessType, Mode=TwoWay}"
SelectedItem="{Binding Path=LogFileProcessType, Mode=TwoWay}"
ItemsSource="{Binding Path=AvailableLogFileProcessTypes}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

See Damascus response for thought process.
Need to Specify UpdateSourceTrigger on CellTemplate / CelLEditTemplate. This triggers the property change.
<DataGridTemplateColumn Header="template">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding Path=LogFileProcessType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=AvailableLogFileProcessTypes}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding Path=LogFileProcessType, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=AvailableLogFileProcessTypes}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Try to add this to your ComboBox :
<ComboBox SelectedValue="{Binding Path=LogFileProcessType, Mode=TwoWay}"
SelectedItem="{Binding Path=LogFileProcessType, Mode=TwoWay}"
ItemsSource="{Binding Path=AvailableLogFileProcessTypes, UpdateSourceTrigger=PropertyChanged}"/>
Therefore, with an UpdateSourceTrigger set to PropertyChanged, each time the object AvailableLogFileProcessTypes will change and call OnPropertyChanged, the ItemsSource will be refreshed.

Related

Textbox in a Combobox with Bindings

I want to display a Textbox in my combobox, for the case, that the desired value is not part of the "Info" Array.
<ComboBox ItemsSource="{Binding Info}"
DisplayMemberPath="Key"
SelectedValuePath="Key"
IsEditable="True"
SelectedIndex="{Binding SelectedIndex, Mode=OneWay}"
SelectedValue="{Binding DesiredVersion}">
</ComboBox>
Just Set ReadOnly to False!
<ComboBox ItemsSource="{Binding Info}"
DisplayMemberPath="Key"
SelectedValuePath="Key"
IsEditable="True"
SelectedIndex="{Binding SelectedIndex, Mode=OneWay}"
SelectedValue="{Binding DesiredVersion}"
IsReadOnly="False">
</ComboBox>
Hope it helped!

WPF DataGrid Combobox Binding

I tried changing DataGridComboBoxColumn to DataGridTemplateColumn without success.
The DataGridComboBoxColumn is working as expected but the Combobox in DataGridTemplateColumn is not. If I change a value in this Combobox, it will change all the visible Comboboxes values in all visible Rows.
What I'm I missing ?
DataGrid is like this:
<DataGrid x:Name="bookDataGrid"
AutoGenerateColumns="False"
EnableRowVirtualization="True"
ItemsSource="{Binding Source={StaticResource bookViewSource}}">
The DataGridComboboxColumn like this:
<DataGridComboBoxColumn x:Name="countryColumn"
ItemsSource="{Binding Source={StaticResource countryLookup}}"
DisplayMemberPath="CountryName"
SelectedValuePath="ID"
SelectedValueBinding="{Binding Country,UpdateSourceTrigger=PropertyChanged}"
Header="Country"
Width="SizeToCells" />
It is used to set the Country (ID) in Books Table. I use CollectionViewSource for Books (bookViewSource) and Country (countryLookup).
The not working DataGridTemplateColumn like this:
<DataGridTemplateColumn x:Name="CountryTemplateColumn">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<ComboBox x:Name="CountryCombo"
ItemsSource="{Binding Source={StaticResource countryLookup}}"
DisplayMemberPath="CountryName"
SelectedValuePath="ID"
SelectedValue="{Binding Country, Source={StaticResource bookViewSource}, UpdateSourceTrigger=PropertyChanged}">
</ComboBox>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Please Help. Thanks.
This solved my Problem:
Add IsSynchronizedWithCurrentItem="False" to the Combobox in the DataGridTemplateColumn and remove the Source={StaticResource bookViewSource} as mm8 suggested.
Remove Source={StaticResource bookViewSource}:
<ComboBox x:Name="CountryCombo"
ItemsSource="{Binding Source={StaticResource countryLookup}}"
DisplayMemberPath="CountryName"
SelectedValuePath="ID"
SelectedValue="{Binding Country, UpdateSourceTrigger=PropertyChanged}">
</ComboBox>

WPF XAML: Why SelectedItem is not working on ListBox when I click ComboBox in it?

Why SelectedItem is not working on ListBox when I click ComboBox in it, below the code:
<ListBox SelectedItem="{Binding MySelectedItemDataGrid}>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<ComboBox />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I need to get the SelectedItem in ListBox, when I click ComboBox.
Thank you
Instead of using ListBox I am using DataGrid.
<DataGrid ItemsSource="{Binding MyItemsSourceDataGrid}"
HeadersVisibility="None"
GridLinesVisibility="None"
SelectedItem="{Binding MySelectedItemDataGrid}">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding MyItemsSourceComboBox}"
SelectedItem="{Binding MySelectedItemComboBox, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Thank you.

WPF Datagrid TemplateColumn Control Enable and Disable

I have Datagrid with two TemplateColumn.
First column is a Combobox and Second column with Extended IntergerUpDown control
I need to Enable/Disable the IntegerUpDown control based on the Combox box SelectedItem value.
Please help me how to accomplish this. Sample xaml below.
<Grid><DataGrid ItemsSource="{Binding List1}" Name="x1">
<DataGrid.Columns>
<DataGridTemplateColumn Header="ColorTemplate">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding DataContext.List2, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}}"
DisplayMemberPath="Name" SelectedValue="{Binding ColourId}" SelectedValuePath="Id" Tag="{Binding Id}"
HorizontalAlignment="Stretch" x:Name="discussTemplate" VerticalAlignment="Stretch"
/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="UPDown" Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<extToolkit:IntegerUpDown AllowSpin="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Minimum="0"
x:Name="updown"
IsEnabled="????" >
</extToolkit:IntegerUpDown>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
This can be easily done with a DataTrigger on your ViewModel ColourId property.
As your SelectedValue property on the ComboBox is already binded, you can have a DataTrigger on your extToolkit:IntegerUpDown control that will set IsEnabled to True/False based on ColourId value on your ViewModel.

WPF4 DataGridComboBoxColumn doesn't work

Look how odd is the following scenario:
<DataGrid.Columns>
<!--Doesn't work-->
<DataGridComboBoxColumn
Header="Vendor"
ItemsSource="{Binding Vendors}"
SelectedItemBinding="{Binding Vendor,
UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Contact.Title"/>
<!--Works-->
<DataGridTemplateColumn Header="Vendor">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock DataContext="{Binding Vendor}"
Text="{Binding Contact.Title}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Vendors}"
SelectedItem="{Binding Vendor, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Contact.Title"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
I posted a connection to Microsft.
Microsoft explained to me, that since the common use of the ItemsSource property of the DataGridComboBoxColumn is to bind it to StaticResource or to any other resource that is not different for each row, it's evaluated with the DataGrid once, not per row, so in order to update the ItemsSource for each row individually, a DataGridTemplateColumn and an inner ComboBox, which this one's ItemsSource does bind per row.

Resources