我创建了一个自定义控件来搜索列表中的客户或直接输入客户代码:
当用户输入客户代码并且文本框失去焦点时,应触发事件。我可以将它用于独立控件,但只要我将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}" />
答案 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>
这不是理想的,但它可以胜任。