We have an editabled Combobox(Cb1) which has a customised Popup with another editable Combobox(Cb2). Below is the sample code
public class ExComboBox : ComboBox
{
public static readonly DependencyProperty CustomPopupProperty = DependencyProperty.Register(
"CustomPopup",
typeof(FrameworkElement),
typeof(ExComboBox),
new PropertyMetadata((d, e) =>
{
}));
public FrameworkElement CustomPopup
{
get { return (FrameworkElement)GetValue(CustomPopupProperty); }
set { SetValue(CustomPopupProperty, value); }
}
static ExComboBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ExComboBox), new FrameworkPropertyMetadata(typeof(ExComboBox)));
}
}
With in the XAML we have a CustomControl which will show the binded 'Popup'.
<ControlTemplate x:Key="ExComboBoxTemplate" TargetType="{x:Type local:ExComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0" />
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom" >
<Themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" >
<Border x:Name="dropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<ContentControl Content="{TemplateBinding CustomPopup}" />
</Border>
</Themes:SystemDropShadowChrome>
</Popup>
<ToggleButton x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxToggleButton}" />
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Content="{TemplateBinding SelectionBoxItem}" />
</Grid>
<ExComboBox x:Name="Cb1" IsEditable="True" Text="{Binding Value1, UpdateSourceTrigger=LostFocus}"
HorizontalAlignment="Left">
<ExComboBox.CustomPopup >
<StackPanel Margin="5">
<GroupBox>
<GroupBox.Header>
<TextBlock Text="My Header" />
</GroupBox.Header>
<StackPanel Margin="5">
<TextBlock Text="Select or Enter value" />
<ComboBox x:Name="Cb2"
IsEditable="True"
Text="{Binding Value2}"
IsTextSearchEnabled="True"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Value2Collection}"
VerticalAlignment="Center" />
<!-- Other controls -->
</StackPanel>
</GroupBox>
</StackPanel>
</ExComboBox.CustomPopup >
</ExComboBox>
We also has some validation on the values that has been entered on both the comboboxes. When I tried to enter the value in Cb2, Cb1's previewTextInput is getting called first, instead of Cb2. I am expecting Cb2 will handle first as Cb2 got the keyboardfocus. When looked into the properties 'HasEffectiveKeyboardFocus ' is always showing the right value, but not 'IsKeyboardFocused'.
Could you please let me know the difference between HasEffectiveKeyboardFocus & IskeyboardFocused. Or how can I get the right focused element, so that I can ignore Cb1's previewTextInput while entering value in Cb2. ( I can't use 'HasEffectiveKeyboardFocus as it is protected proeprty) Thanks in advance.