在自定义控件中处理TextBox的LostFocus事件

时间:2015-05-19 12:06:07

标签: wpf custom-controls

我创建了一个自定义控件来搜索列表中的客户或直接输入客户代码:

enter image description here

当用户输入客户代码并且文本框失去焦点时,应触发事件。我可以将它用于独立控件,但只要我将XAML放入模板中,LostFocus事件就不再触发了。

我在某处读过“交互触发器”在样式/模板中不起作用。在底层TextBox上使用LostFocus功能创建可重用MVVM控件的正确方法是什么?

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>

实施

    <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}" />

1 个答案:

答案 0 :(得分:1)

我在这些场景中使用过数据模板: -

<DataTemplate x:Key="foo"
              DataType="{x:Type custom_controls:CustomerSelectorField}">
    <Grid wpf:MarginSetter.Margin="0,0,5,0">
        ...
    </Grid>
</DataTemplate>

(您需要将InvokeCommandAction绑定从“{TemplateBinding ...}”更改为“{Binding ...}”。)

您的控件的XAML保持不变,但您需要将其包装在ContentControl中,然后将数据模板应用于: -

<ContentControl ContentTemplate="{StaticResource foo}">
    <custom_controls:CustomerSelectorField ....
</ContentControl>

这不是理想的,但它可以胜任。