I have created a custom control to search a customer in a list or by entering the customer code directly:
When a user enters a customer code and the textbox loses focus, an event should trigger. I can get this to work on a standalone control but as soon as I put the XAML in a template, the LostFocus event doesn't trigger anymore.
I've read somewhere that the Interaction Triggers don't work in styles/templates. What is the correct way to create a reusable MVVM control with LostFocus functionality on an underlying TextBox?
CustomerSelectorField.cs
public class CustomerSelectorField : Control
{
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
// Using a DependencyProperty as the backing store for Command. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(CustomerSelectorField), new PropertyMetadata(null));
public ICommand LostFocusCommand
{
get { return (ICommand)GetValue(LostFocusCommandProperty); }
set { SetValue(LostFocusCommandProperty, value); }
}
// Using a DependencyProperty as the backing store for LostFocusCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LostFocusCommandProperty =
DependencyProperty.Register("LostFocusCommand", typeof(ICommand), typeof(CustomerSelectorField), new PropertyMetadata(null));
}
XAML
<Style TargetType="{x:Type custom_controls:CustomerSelectorField}">
<Setter Property="FocusManager.IsFocusScope" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type custom_controls:CustomerSelectorField}">
<Grid wpf:MarginSetter.Margin="0,0,5,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBox Text="{Binding CustomerCode}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<i:InvokeCommandAction Command="{TemplateBinding LostFocusCommand}" CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<custom_controls:IconButton
Grid.Column="1"
Command="{TemplateBinding Command}"
CommandParameter="{Binding}" />
<TextBox IsReadOnly="True" Text="{Binding Name, Mode=OneWay}" Grid.Column="2" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Implementation
<custom_controls:CustomerSelectorField DataContext="{Binding ParentAcc}" LostFocusCommand="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.ParentCustomerLostFocusCommand}" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.OpenParentCustomerSelectorCommand}" />