0
votes

I have a ComboBox in WPF which is databound, and has data template which controls how each of the items is displayed. I have made it so that each item is displayed with two bits of text (for the Name and Path properties) and one image (for the Icon property).

At the moment when I select an item from the ComboBox the textbox bit of the ComboBox just changes to say "TestWPF.Result" which is the name of the class which I have populated the ComboBox with.

I'm interested in one (or both) of two things:

  1. How do I change it so that it displays the value of one of the fields there (eg. so it shows the value of the Name field rather than the name of the class)?

  2. Is it possible get it to use the same DataTemplate there as in the list of items, so that once I have selected an item it displays in the closed ComboBox the same way as it looks in the list of items. Basically I've got a DataTemplate called ShowResults and a ComboBox which uses that template. I've also added in a separate ContentControl which I've got to show the details of the selected item in the ComboBox, but I want to get that to replace the textbox in the ComboBox.

Update:

Thanks for the first answer. I've tried using a separate ContentControl, as you've described, and it works fine. The question now is how to replace the textbox part of the ComboBox with this ContentControl. Any hints on that would be most welcome.

Also, is it possible to replace the textbox bit of the ComboBox control with a mixture of the ContentControl and a textbox, so that I can still type in the textbox to help select items from the ComboBox, but then when I close the dropdown the rest ContentControl bit will be populated with the rest of the text and the icon. Hope that makes sense - ask questions if it doesn't!

Code:

I've been asked to post my code - so here it is. I've tried to remove things that I know are definitely not relevant, but I'm not sure exactly what is relevant so when in doubt I've left things in.

<Window x:Class="TestWPF.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:TestWPF"
Title="Window1" Height="300" Width="843" Loaded="Window_Loaded">
<Window.Resources>
    <DataTemplate x:Key="ShowResult" DataType="TestWPF.Result">
        <StackPanel Margin="5" Orientation="Horizontal">
            <Image Width="32" Height="32"  Source="{Binding Path=Image}"/>
            <StackPanel Margin="5">
                <TextBlock FontWeight="Bold" Text="{Binding Path=Name}"/>                    
                <TextBlock Text="{Binding Path=Path}"/>
            </StackPanel>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

<Grid Width="786">
    <Button Height="23" HorizontalAlignment="Right" Margin="0,24,166,0" Name="btnTest" VerticalAlignment="Top" Width="75" Click="btnTest_Click">Add</Button>
    <ComboBox StaysOpenOnEdit="True"  DropDownClosed="comboBox1_DropDownClosed" PreviewTextInput="comboBox1_PreviewTextInput" SelectionChanged="comboBox1_SelectionChanged" ItemTemplate="{StaticResource ShowResult}"  Margin="259,109,22,89" Name="comboBox1" IsEditable="True" />
    <ContentControl Height="50" Margin="268,0,22,21" Name="contentControl1" VerticalAlignment="Bottom" Content="{Binding ElementName=comboBox1,Path=SelectedValue}" ContentTemplate="{StaticResource ShowResult}"/>
</Grid>

2

2 Answers

1
votes

You got the binding part right - binding to the data and using a DataTemplate to display the source the way you want to.

As to your second question, a way to do it would be to use a ComboBox with IsEditable="True" as you have, and withing the TextChanged event handler check if the comboBox.Items contains the new value, if not check use Linq to seach for a match:

if (comboBox.Items.Contains(e.NewValue))
    return;
var matches = with comboBox.Items select item where item.BeginsWith(e.NewValue);
if (matches.Count > 0) comboBox.SelectedItem = matches.First();
0
votes

Just place the Property Binding expression to the textBox,You dont need to apply template.

Another way to get exact Data template, Place a ContentControl in the place of textBox and assign the same DataTemplate (say x:Name="robinTemplate")

<ContentControl Content="{Binding ElementName=cmbBox,Path=SelectedValue}" ContentTemplate="{StaticResource robinTemplate}"/>

For making the Selected content display in the same way : Create a copy of the combobox control template and you will find a ContentPresenter there. Replace that with the ContentControl.. This is not the right solution though.