<Window
x:Class="WidgetSearch3000.Window1"
x:Name="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:WidgetSearch3000"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding ElementName=MainWindow}"
Height="300"
Icon="SearchIcon.png"
Title="Widget Searcher 3001"
Width="300">
<Window.Resources>
<local:TextFormatterConverter x:Key="TextFormatter" />
<Style
x:Key="FoundTextStyle"
TargetType="{x:Type Run}">
<Setter Property="Foreground" Value="Red" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Run.TextDecorations" Value="Underline" />
</Style>
<Style
x:Key="searchTextBox"
TargetType="TextBox">
<Setter Property="FontSize" Value="12pt" />
<Setter Property="FontFamily" Value="Tahoma" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<!-- This is the custom control template we will apply to the TextBox -->
<ControlTemplate TargetType="TextBox">
<Border
Background="WhiteSmoke"
BorderBrush="LightSteelBlue"
BorderThickness="6"
CornerRadius="7"
Padding="7">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="ContactTemplate">
<Grid Margin="5, 5, 5, 5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform
ScaleX="1"
ScaleY="1" />
</TransformGroup>
</Grid.RenderTransform>
<Border
x:Name="Grid"
BorderBrush="Black"
BorderThickness="1.5"
CornerRadius="10"
Grid.Row="1"
Height="50"
Padding="5"
VerticalAlignment="Stretch">
<Border.Background>
<SolidColorBrush
x:Name="HighlightBrushName"
Color="WhiteSmoke" />
</Border.Background>
<TextBlock
x:Name="Text"
FontSize="15"
HorizontalAlignment="Stretch"
VerticalAlignment="Center">
<TextBlock.IsEnabled>
<MultiBinding Converter="{StaticResource TextFormatter}">
<Binding Path="FullName" />
<Binding
ElementName="tSearchString"
Path="Text" />
<Binding RelativeSource="{RelativeSource Self}" />
<Binding Source="{StaticResource FoundTextStyle}" />
</MultiBinding>
</TextBlock.IsEnabled>
</TextBlock>
</Border>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True">
<Setter Property="BitmapEffect" TargetName="Grid">
<Setter.Value>
<DropShadowBitmapEffect />
</Setter.Value>
</Setter>
<Setter Property="Foreground" TargetName="Text" Value="Black" />
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Duration="00:00:01"
Storyboard.TargetName="HighlightBrushName"
Storyboard.TargetProperty="Color"
To="#FFFDFF2F" />
<DoubleAnimation
Duration="00:00:00.50"
Storyboard.TargetName="Grid"
Storyboard.TargetProperty="Height"
To="60" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Duration="00:00:00.50"
Storyboard.TargetName="HighlightBrushName"
Storyboard.TargetProperty="Color"
To="WhiteSmoke" />
<DoubleAnimation
Duration="00:00:00.50"
Storyboard.TargetName="Grid"
Storyboard.TargetProperty="Height"
To="50" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid
Grid.Row="1"
VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Label
x:Name="label1"
FontSize="12"
FontWeight="Bold"
Grid.Column="0"
Height="28">
Search:
</Label>
<TextBox
x:Name="tSearchString"
Grid.Column="1"
HorizontalAlignment="Stretch"
Style="{StaticResource searchTextBox}"
TextChanged="tSearchString_TextChanged" />
</Grid>
<GroupBox
x:Name="groupBox1"
Grid.Row="2"
Header="Results"
VerticalAlignment="Stretch">
<ListBox
x:Name="listOfPeople"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding FoundPeople}"
ItemTemplate="{StaticResource ContactTemplate}"
Padding="3"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.Resources>
<SolidColorBrush
x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent" />
</ListBox.Resources>
</ListBox>
</GroupBox>
</Grid>
</Window>
namespace WidgetSearch3000 {
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Collections.ObjectModel;
public class TextFormatterConverter : IMultiValueConverter {
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
var name = values[0] as String;
if (name == null) {
return true;
}
var nameLower = name.ToLower();
var search = values[1] as String;
if (search == null) {
return true;
}
var searchLower = search.ToLower();
var t = values[2] as TextBlock;
if (t == null) {
return true;
}
var runStyle = values[3] as Style;
if (runStyle == null) {
return true;
}
t.Inlines.Clear();
Run run;
int index = nameLower.IndexOf(searchLower);
if (!searchLower.Equals("")) {
while (index != -1) {
if (index != 0) {
run = new Run();
//run.Foreground = Brushes.Black;
run.Text = name.Substring(0, index);
t.Inlines.Add(run);
}
run = new Run();
run.Text = name.Substring(index, search.Length);
run.Style = runStyle;
t.Inlines.Add(run);
name = name.Substring(index + search.Length);
nameLower = nameLower.Substring(index + search.Length);
index = nameLower.IndexOf(searchLower);
}
}
if (!name.Equals("")) {
run = new Run();
//run.Foreground = Brushes.Black;
run.Text = name;
t.Inlines.Add(run);
}
return true;
//}
//return string.Format("this is a test: {0} {1}", values[0], values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
}
#endregion
}
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window {
private List<Person> m_lsPeople;
private ObservableCollection<Person> m_lsFound = new ObservableCollection<Person>();
public Window1() {
InitializeComponent();
//m_lsFound = new ObservableCollection<Person>();
m_lsPeople = new List<Person>();
m_lsPeople.Add(new Person("Paul", "Machinroe"));
m_lsPeople.Add(new Person("Frank", "Smith"));
m_lsPeople.Add(new Person("Joe", "Yakk"));
m_lsPeople.Add(new Person("Grant", "Wellington"));
m_lsPeople.Add(new Person("Lucy", "Fiat"));
m_lsPeople.Sort();
//DataContext = this;
Search();
}
public void Search() {
// m_lsFound.Clear();
Boolean hasAdded = false;
foreach (Person person in m_lsPeople) {
if (!person.Contains(tSearchString.Text)) {
m_lsFound.Remove(person);
} else if (!m_lsFound.Contains(person)) {
hasAdded = false;
for (int i = 0; i < m_lsFound.Count; i++) {
if (person.CompareTo(m_lsFound[i]) < 0) {
m_lsFound.Insert(i, person);
hasAdded = true;
break;
}
}
if (!hasAdded) {
m_lsFound.Add(person);
}
}
}
}
public ObservableCollection<Person> FoundPeople {
get {
return m_lsFound;
}
set {
m_lsFound = value;
}
}
private void tSearchString_TextChanged(object sender, TextChangedEventArgs e) {
Search();
}
}
}