Textbox in a Combobox with Bindings - wpf

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!

Related

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>

Datatemplate for combobox not switching selected value when binded with Entity Framework

At runtime all the items are selected with the same item.
How can I make it so that it will all be binded to their respective Datacontext?
<ComboBox ItemsSource="{Source={StaticResource CalculationTypesLookUp}}" Grid.Row="1" Grid.Column="1"
DisplayMemberPath="CalculationTypeDescription"
SelectedValuePath="Id"
SelectedValue="{Binding CalculationTypeId, Mode=TwoWay}"/>
If you add IsSynchronizedWithCurrentItem="False" it will fix your issue.
By default it will be set to true IsSynchronizedWithCurrentItem="True"
making all the datatemplate instances the same.
<ComboBox ItemsSource="{Binding Source={StaticResource CalculationTypesLookUp}}" Grid.Row="1" Grid.Column="1"
DisplayMemberPath="CalculationTypeDescription"
SelectedValuePath="Id"
SelectedValue="{Binding CalculationTypeId, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="False"/>

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.

Cascading Combobox in DataGrid using DataTemplate Cross-Cell Binding

If I place my cascading comboboxes inside the same DataTemplate in a WPF DataGrid cell - the binding works properly (via ElementName). However, from a UI perspective I want my comboboxes to physically reside in different cells, not the same datagrid cell. How do you make cross-cell binding work (between DataTemplates) using DataGridTemplateColumns? It seems the issue is that the second comboboxes' ItemsSource cannot find the ElementName for binding when the comboboxes exist in different DataTemplate columns.
This works....
<DataGrid x:Name="grdItems" AutoGenerateColumns="false" ItemsSource="{Binding Model}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Car Make / Model" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="cbCarMake" SelectedItem="{Binding CarMake, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.CarMakes, Mode=TwoWay}" DisplayMemberPath="Name" SelectedValuePath="ID">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<mvvm:EventToCommand Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.SelectCarMake}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
<ComboBox SelectedItem="{Binding CarModel, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding ElementName=cbCarMake, Path=Tag.CarModels, Mode=TwoWay}" DisplayMemberPath="Name" SelectedValuePath="ID"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
This doesn't....
<DataGrid x:Name="grdItems" AutoGenerateColumns="false" ItemsSource="{Binding Model}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Car Make" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="cbCarMake" SelectedItem="{Binding CarMake, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.CarMakes, Mode=TwoWay}" DisplayMemberPath="Name" SelectedValuePath="ID">
<i:Interaction.Triggers>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<mvvm:EventToCommand Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.SelectCarMake}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</i:Interaction.Triggers>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Car Model" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding CarModel, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding ElementName=cbCarMake, Path=Tag.CarModels, Mode=TwoWay}" DisplayMemberPath="Name" SelectedValuePath="ID"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
The trick with cross-data template binding is to use the ViewModel as a go-between. When properties change on the view model (an ObservableCollection in this case), you can trigger this notification to the dependent listeners (elements listening to PropertyChanged events).
The issue for me was that the View Model wasn't receiving the PropertyChanged notifications it should have been. I assumed that the mvvm-light ObservableObject automatically triggered PropertyChanged events for all properties.
You must use the mvvminpcset code snippet which explicitly raises property change events for the items in your ObservableCollection. Once the PropertyChanged events started firing, the ItemSource binding worked as seen below.
<DataGrid x:Name="grdItems" AutoGenerateColumns="false" ItemsSource="{Binding Model}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Car Make" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="cbCarMake" SelectedItem="{Binding CarMake, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.CarMakes, Mode=TwoWay}" DisplayMemberPath="Name" SelectedValuePath="ID">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Car Model" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding CarModel, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding CarMake.CarModels}" DisplayMemberPath="Name" SelectedValuePath="ID"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

WPF Data Binding ComboBox in DataGridTemplateColumn

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.

Resources