Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ItemTemplate does not affect selected item of AutoCompleteBox

I'm using wpf toolkit AutoCompleteBox and I've set the Item template. The problem : the Items in the pop-up list look great but it didn't take effect on the textbox above (the selected item).

alt text

XAML:

 <Controls:AutoCompleteBox x:Name="x" ItemFilter="SearchPerson" Margin="20">
        <Controls:AutoCompleteBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Name}" />
                    <Rectangle Width="10" Height="10" Fill="LightGreen"/>
                    <TextBlock Text="{Binding Age}" />
                </StackPanel>    
            </DataTemplate>
        </Controls:AutoCompleteBox.ItemTemplate>
    </Controls:AutoCompleteBox>

Code behind:

 public partial class MainWindow : Window
{
    public List<Person> Persons { get; set; }

    public MainWindow() {
        InitializeComponent();

        Persons = new List<Person> {
            new Person{Name = "Jhon",Age=35},                           
            new Person{Name = "Kelly",Age=40}};


        x.ItemsSource = Persons;
        DataContext = this;
    }

    bool SearchPerson(string search, object value) {
        return (value as Person).Name.ToLower().Contains(search);
    }
}

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
like image 247
Erez Avatar asked Jan 06 '11 17:01

Erez


1 Answers

What do you want to show in the TextBox? To display the Name of the Selected person you may add ValueMemberPath like this

<Controls:AutoCompleteBox x:Name="x" ItemFilter="SearchPerson" Margin="20"
                          ValueMemberPath="Name">

If you want to display both Name and Age in the TextBox you can use ValueMemberBinding with a converter

<Controls:AutoCompleteBox x:Name="x" ItemFilter="SearchPerson" Margin="20"
          ValueMemberBinding="{Binding Converter={StaticResource PersonConverter}}">

Where we bind directly to the Person and return Name and Age in the converter

public class PersonConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Person person = value as Person;
        if (person != null)
        {
            return person.Name + " : " + person.Age.ToString();
        }
        return string.Empty;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Update

You'll have to edit the Template of the AutoCompleteBox. TextBox can't display a Rectangle so the solution will be depending on how you want this to be handled. Here is an example that displays a TextBox, a Rectangle and a TextBlock in the Template. It should give you what you want

alt text

<Controls:AutoCompleteBox x:Name="x" ItemFilter="SearchPerson" Margin="20" Grid.Row="0"
                            ValueMemberPath="Name"
                            Style="{DynamicResource AutoCompleteBoxStyle1}">
    <Controls:AutoCompleteBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" />
                <Rectangle Width="10" Height="10" Fill="LightGreen"/>
                <TextBlock Text="{Binding Age}" />
            </StackPanel>
        </DataTemplate>
    </Controls:AutoCompleteBox.ItemTemplate>
</Controls:AutoCompleteBox>

<Style x:Key="AutoCompleteBoxStyle1" TargetType="{x:Type Controls:AutoCompleteBox}">
    <Setter Property="IsTabStop" Value="False"/>
    <Setter Property="Padding" Value="2"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="BorderBrush">
        <Setter.Value>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FFA3AEB9" Offset="0"/>
                <GradientStop Color="#FF8399A9" Offset="0.375"/>
                <GradientStop Color="#FF718597" Offset="0.375"/>
                <GradientStop Color="#FF617584" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="Background" Value="White"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="MinWidth" Value="45"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Controls:AutoCompleteBox}">
                <Grid Opacity="{TemplateBinding Opacity}">
                    <TextBox x:Name="Text" Opacity="1" Visibility="Visible" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" IsTabStop="True" Margin="0" Padding="{TemplateBinding Padding}" Style="{TemplateBinding TextBoxStyle}"/>
                    <StackPanel Name="stackPanel"  Orientation="Horizontal" VerticalAlignment="Top" Visibility="Visible" IsHitTestVisible="False" Grid.ZIndex="1">
                        <TextBlock Margin="6,9,0,0"
                                    VerticalAlignment="Center"
                                    Opacity="0"
                                    Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Controls:AutoCompleteBox}},
                                                    Path=SelectedItem.Name}" />
                        <Rectangle Width="10" Height="10" VerticalAlignment="Center" Fill="LightGreen" />
                        <TextBlock VerticalAlignment="Center"
                                    Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Controls:AutoCompleteBox}},
                                                    Path=SelectedItem.Age}"/>
                    </StackPanel>
                    <Border x:Name="ValidationErrorElement" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1" Visibility="Collapsed">
                        <Border.ToolTip>
                            <ToolTip x:Name="validationTooltip" Placement="Right">
                                <ToolTip.Triggers>
                                    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                                        <BeginStoryboard>
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="validationTooltip">
                                                    <DiscreteObjectKeyFrame KeyTime="0">
                                                        <DiscreteObjectKeyFrame.Value>
                                                            <System:Boolean>True</System:Boolean>
                                                        </DiscreteObjectKeyFrame.Value>
                                                    </DiscreteObjectKeyFrame>
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </EventTrigger>
                                </ToolTip.Triggers>
                                <ToolTip.Template>
                                    <ControlTemplate TargetType="{x:Type ToolTip}">
                                        <Grid x:Name="Root" Margin="5,0" Opacity="0" RenderTransformOrigin="0,0">
                                            <Grid.RenderTransform>
                                                <TranslateTransform X="-25"/>
                                            </Grid.RenderTransform>
                                            <Border Background="#052A2E31" CornerRadius="5" Margin="4,4,-4,-4"/>
                                            <Border Background="#152A2E31" CornerRadius="4" Margin="3,3,-3,-3"/>
                                            <Border Background="#252A2E31" CornerRadius="3" Margin="2,2,-2,-2"/>
                                            <Border Background="#352A2E31" CornerRadius="2" Margin="1,1,-1,-1"/>
                                            <Border Background="#FFDC000C" CornerRadius="2">
                                                <TextBlock Foreground="White" MaxWidth="250" Margin="8,4" TextWrapping="Wrap" Text="{Binding (Validation.Errors)[0].ErrorContent}"/>
                                            </Border>
                                        </Grid>
                                    </ControlTemplate>
                                </ToolTip.Template>
                            </ToolTip>
                        </Border.ToolTip>
                        <Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">
                            <Path Data="M1,0L6,0A2,2,90,0,1,8,2L8,7z" Fill="#FFDC000C" Margin="1,3,0,0"/>
                            <Path Data="M0,0L2,0 8,6 8,8" Fill="White" Margin="1,3,0,0"/>
                        </Grid>
                    </Border>
                    <Popup x:Name="Popup">
                        <Grid Background="{TemplateBinding Background}" Opacity="{TemplateBinding Opacity}">
                            <Border x:Name="PopupBorder" BorderThickness="0" Background="#11000000" HorizontalAlignment="Stretch" >
                                <Border.RenderTransform>
                                    <TranslateTransform X="1" Y="1"/>
                                </Border.RenderTransform>
                                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0" HorizontalAlignment="Stretch" Opacity="1" Padding="0">
                                    <Border.Background>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#FFDDDDDD" Offset="0"/>
                                            <GradientStop Color="#AADDDDDD" Offset="1"/>
                                        </LinearGradientBrush>
                                    </Border.Background>
                                    <Border.RenderTransform>
                                        <TransformGroup>
                                            <TranslateTransform X="-1" Y="-1"/>
                                        </TransformGroup>
                                    </Border.RenderTransform>
                                    <ListBox x:Name="Selector" BorderThickness="0" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ItemTemplate="{TemplateBinding ItemTemplate}" ItemContainerStyle="{TemplateBinding ItemContainerStyle}" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
                                </Border>
                            </Border>
                        </Grid>
                    </Popup>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="SelectedItem" Value="{x:Null}">
                        <Setter TargetName="stackPanel" Property="Visibility" Value="Hidden"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
like image 180
Fredrik Hedblad Avatar answered Oct 01 '22 22:10

Fredrik Hedblad