I wanted to get ScrollIntoView(SelectedItem); and highlight the selected item when initialized (tried to manually set the item to the 21st record just for testing purposes). It works fine if I manually select the item but doesn't work if I manually try to set the initial selectitem. This is based onhttp://www.eggheadcafe.com/tutorials/aspnet/5af72df7-5b0b-4ac2-be96-e24127040bbf/wpf-datagrid-as-combobox-dropdown-part-2.aspx[^]
Here is the code:
Window1.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Forms;
namespace WPFDataGridAsComboBoxDropdown
{
public partial class Window1 : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Customer selectedCustomer;
private bool isEditingCustomer;
Microsoft.Windows.Controls.DataGrid grid = null;
public Window1()
{
InitializeComponent();
SelectedCustomer = CustomerList[21];
ComboBox1.SelectedIndex = 21;
ComboBox1.SelectedItem = CustomerList[21];
}
public Customer SelectedCustomer
{
get
{
return selectedCustomer;
}
set
{
if (object.ReferenceEquals(selectedCustomer, value) != true)
{
selectedCustomer = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("SelectedCustomer"));
}
IsEditingCustomer = false;
}
}
}
public bool IsEditingCustomer
{
get
{
return isEditingCustomer;
}
set
{
if (isEditingCustomer.Equals(value) != true)
{
isEditingCustomer = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsEditingCustomer"));
}
}
}
}
private void OnLoadedGrid(object sender, RoutedEventArgs e)
{
grid = (Microsoft.Windows.Controls.DataGrid)sender;
if (ComboBox1.SelectedItem != null && grid != null)
{
grid.UpdateLayout();
grid.UpdateLayout();
grid.ScrollIntoView(ComboBox1.SelectedItem);
}
}
Customers _CustomerList = new Customers();
public Customers CustomerList
{
get { return _CustomerList; }
set { _CustomerList = value; }
}
}
public class MyDataGrid : Microsoft.Windows.Controls.DataGrid
{
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
ScrollIntoView(SelectedItem);
}
}
public class Customers : ObservableCollection<Customer>
{
public Customers()
{
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
Add(new Customer { Name = "Mike", Address = "Canada", TelephoneNumber = "748-9763" });
Add(new Customer { Name = "Bill", Address = "Japan", TelephoneNumber = "839-3858" });
Add(new Customer { Name = "John", Address = "USA", TelephoneNumber = "123-4567" });
}
}
public class Customer
{
public string Name { get; set; }
public string Address { get; set; }
public string TelephoneNumber { get; set; }
}
}
Here is Window1.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFDataGridAsComboBoxDropdown"
x:Class="WPFDataGridAsComboBoxDropdown.Window1"
Title="Window1"
SizeToContent="WidthAndHeight"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
xmlns:mytoolkit="clr-namespace:WPFDataGridAsComboBoxDropdown">
<Window.Resources>
<local:Customers x:Key="Customers"/>
<Style x:Key="ComboBoxFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle SnapsToDevicePixels="true" Margin="4,4,21,4" Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
<Geometry x:Key="DownArrowGeometry">M 0 0 L 3.5 4 L 7 0 Z</Geometry>
<Style x:Key="ComboBoxReadonlyToggleButton" TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" x:Name="Chrome" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}">
<Grid HorizontalAlignment="Right" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
<Path HorizontalAlignment="Center" Margin="3,1,0,0" x:Name="Arrow" VerticalAlignment="Center" Fill="Black" Data="{StaticResource DownArrowGeometry}"/>
</Grid>
</Microsoft_Windows_Themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" StartPoint="0,0" MappingMode="Absolute">
<GradientStop Color="#ABADB3" Offset="0.05"/>
<GradientStop Color="#E2E3EA" Offset="0.07"/>
<GradientStop Color="#E3E9EF" Offset="1"/>
</LinearGradientBrush>
<Style x:Key="ComboBoxEditableTextBox" TargetType="{x:Type TextBox}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="MinWidth" Value="0"/>
<Setter Property="MinHeight" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<ScrollViewer Focusable="false" Background="Transparent" x:Name="PART_ContentHost" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" x:Name="Chrome" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RoundCorners="false">
<Path HorizontalAlignment="Center" Margin="0,1,0,0" x:Name="Arrow" VerticalAlignment="Center" Fill="Black" Data="{StaticResource DownArrowGeometry}"/>
</Microsoft_Windows_Themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">
<Grid SnapsToDevicePixels="true" x:Name="Placement">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Popup AllowsTransparency="true" IsOpen="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" x:Name="PART_Popup" Grid.ColumnSpan="2">
<Microsoft_Windows_Themes:SystemDropShadowChrome MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding Path=ActualWidth, ElementName=Placement}" x:Name="Shdw" Color="Transparent">
<Border x:Name="DropDownBorder" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1">
<ScrollViewer>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.DirectionalNavigation="Contained"/>
</ScrollViewer>
</Border>
</Microsoft_Windows_Themes:SystemDropShadowChrome>
</Popup>
<Microsoft_Windows_Themes:ListBoxChrome x:Name="Border" Grid.ColumnSpan="2" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" RenderMouseOver="{TemplateBinding IsMouseOver}"/>
<TextBox HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" x:Name="PART_EditableTextBox" Style="{StaticResource ComboBoxEditableTextBox}" IsReadOnly="{Binding Path=IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}"/>
<ToggleButton Style="{StaticResource ComboBoxToggleButton}" Grid.Column="1" IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsDropDownOpen" Value="true">
<Setter Property="RenderFocused" TargetName="Border" Value="true"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="DropDownBorder" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
<Setter Property="Background" Value="#FFF4F4F4"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
<Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/>
<Setter Property="Color" TargetName="Shdw" Value="#71000000"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="ComboBoxStyle1" TargetType="{x:Type ComboBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ComboBoxFocusVisual}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Padding" Value="4,3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type ComboBox}">
<Grid
SnapsToDevicePixels="true"
x:Name="MainGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="*"/>
<ColumnDefinition
MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"
Width="0"/>
</Grid.ColumnDefinitions>
<Popup
AllowsTransparency="true"
IsOpen="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}"
Placement="Bottom"
PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"
Margin="1"
x:Name="PART_Popup"
Grid.ColumnSpan="2">
<Microsoft_Windows_Themes:SystemDropShadowChrome
MaxHeight="{TemplateBinding MaxDropDownHeight}"
MinWidth="{Binding Path=ActualWidth, ElementName=MainGrid}"
x:Name="Shdw"
Color="Transparent">
<Border
x:Name="DropDownBorder"
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"
BorderThickness="1">
<mytoolkit:MyDataGrid
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
ItemsSource="{TemplateBinding ItemsSource}"
AutoGenerateColumns="False"
IsReadOnly="True"
SelectionMode="Single"
HeadersVisibility="All"
SelectionUnit="FullRow"
Loaded="OnLoadedGrid"
SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedItem}">
<mytoolkit:MyDataGrid.Columns>
<toolkit:DataGridTextColumn
Header="Name"
Width="100"
Binding="{Binding Name}"/>
<toolkit:DataGridTextColumn
Header="Address"
Width="100"
Binding="{Binding Address}"/>
<toolkit:DataGridTextColumn
Width="100"
Header="Telephone No."
Binding="{Binding TelephoneNumber}"/>
</mytoolkit:MyDataGrid.Columns>
</mytoolkit:MyDataGrid>
</Border>
</Microsoft_Windows_Themes:SystemDropShadowChrome>
</Popup>
<ToggleButton
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Style="{StaticResource ComboBoxReadonlyToggleButton}"
Grid.ColumnSpan="2"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter
Name="ContentPres"
IsHitTestVisible="false"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger
Property="HasDropShadow"
SourceName="PART_Popup"
Value="true">
<Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/>
<Setter Property="Color" TargetName="Shdw" Value="#71000000"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="DropDownBorder" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
<Setter Property="Background" Value="#FFF4F4F4"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEditable" Value="true">
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="Template" Value="{StaticResource ComboBoxEditableTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<ComboBox
Name="ComboBox1"
Margin="4"
Height="23"
Width="250"
ItemsSource="{StaticResource Customers}"
Style="{DynamicResource ComboBoxStyle1}"
SelectedItem="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=SelectedCustomer}"
IsDropDownOpen="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=IsEditingCustomer}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" Margin="4,0"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</Window>
|