Reputation: 839
I've been searching for quite a while, but cannot figure out how to override the autocomplete functionality in a DataGridComboBoxColumn.
What I want to do is what is explained here, except for a combobox: Searching for items in a list box
That is: I want to be able to enter any string and then apply a filter to the ComboBox items in the DataGridComboBoxColumn to show only those items that match this as a substring.
I'm new to WPF and have been searching online for a while. I've found things like EventSetters and CommandBehaviorCollection.Behaviors, but I can't get a clear picture of the possibilities (and impossibilities).
I've got:
<DataGrid ... >
...
<DataGrid.Columns>
...
<MyCustomDataGridComboBoxColumn Header="My Header" MinWidth="200" >
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding DataContext.MyData, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<Setter Property="SelectedItem" Value="{Binding DataItem, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True}" />
<Setter Property="DisplayMemberPath" Value="HardwareId" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding DataContext.MyFilteredData, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<Setter Property="SelectedItem" Value="{Binding DataItem, UpdateSourceTrigger=LostFocus}" />
<Setter Property="DisplayMemberPath" Value="HardwareId" />
<Setter Property="IsEditable" Value="True"/>
<Setter Property="Text" Value="{Binding DataContext.MyNewDataItem, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</MyCustomDataGridComboBoxColumn>
...
</DataGrid.Columns>
</DataGrid>
Ideally, I'd like to create a new class that inherits from DataGridComboBoxColumn and supply it with some custom logic, such as supplying an anonymous function in its constructor so that the autocomplete behavior can be overridden in different ways in the future.
Is this even possible, or am I going about this entirely the wrong way?
Upvotes: 1
Views: 1337
Reputation: 542
I'm not saying your approach is wrong, however, I would approach it differently. For me it seems easier to use a DataGridTemplateColumn and supply a ComboBox that has the functionality you speak of.
<DataGridTemplateColumn Header="ColumnName" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<YourCustomComboBox/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Edit:
A while ago I needed a ComboBox with the same functionality. I ended up combining a TextBox with a Popup control because it gave me much more control over it.
<TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" x:Name="editBox"/>
<Popup x:Name="textboxPopup" Width="{Binding ElementName=editBox, Path=ActualWidth, Mode=OneWay}"
PlacementTarget="{Binding ElementName=editBox}"
StaysOpen="False"
IsOpen="{Binding Path=IsOpen, Mode=OneWay}">
<Grid>
<DockPanel MaxHeight="500">
<ListView SelectionMode="Single"
ItemsSource="{Binding Path=Suggestions}"
Name="popupList">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"Color="LightBlue"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="LightBlue"/>
</Style.Resources>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="LightBlue"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</DockPanel>
</Grid>
In the codebehind I subscribed to the TextChanged event and a few other events that came in handy. I can't share all my code because it is production code. However there are a few other people on the internet with similar implementations: using a ComboBox, using a textbox and of course the link you posted in your question. There is more than enough out there.
And about using your custom control as a TargetType... I don't see anything wrong with that, I do it all the time.
The error with the CellTemplate shouldn't occur. Are you using it correctly? See this link for an example.
Upvotes: 1