我正在处理WPF MVVM项目。 DataGrid显示服务找到的记录。每行都有一个按钮,该按钮将执行一个与选定记录一起执行的操作。
public class ReferenceDossier
{
}
XAML
<GroupBox>
<Grid>
<StackPanel>
<TextBox>
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding SearchCommand}"/>
</TextBox.InputBindings>
</TextBox>
</StackPanel>
</Grid>
</GroupBox>
<GroupBox>
<Grid>
<StackPanel>
<DataGrid ItemsSource="{Binding ReferenceDossiers}">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Command="{Binding Command}"
CommandParameter="{Binding}">>
<iconPacks:PackIconFontAwesome Kind="PlusCircle" Foreground="#FF94bf00"/>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Grid>
</GroupBox>
当我使用TextBox
中的关键字进行搜索并点击Enter时,它将执行计算并在DataGrid
中显示结果。
我要编码的内容:
如果用户再次按ENTER(在DataGrid
中显示的记录之后)并且用户尚未选择行,则第一行Command
中的Button
必须为在调用网格中的多少条记录(并不重要)时,必须选择第一个。
如果用户在DataGrid
中选择一行并按Enter,则该行Command
中的Button
被调用。
如果记录为零,则什么也不做。
目标是减少在GUI上进行选择的时间。
但是我找不到通过MVVM方法做到这一点的方法。
通过一些尝试,当我点击关键字后按ENTER时,TextBox
始终处于焦点状态。我再次按ENTER,它将重新执行计算。
答案 0 :(得分:0)
您可以使用EventTrigger
来实现。
XAML
<Style TargetType="DataGridRow">
<Style.Triggers>
<local:EnterDownEventTrigger EventName="KeyDown">
<i:InvokeCommandAction Command="{Binding Command}" CommandParameter="{Binding}"/>
</local:EnterDownEventTrigger>
</Style.Triggers>
</Style>
由于只希望通过 Enter 键调用Command
,因此需要为此编写自定义EventTrigger
。
输入键的自定义事件触发器
using System.Windows.Interactivity;
public class EnterDownEventTrigger : EventTrigger
{
public EnterDownEventTrigger() : base("KeyDown") { }
protected override void OnEvent(EventArgs eventArgs)
{
var e = eventArgs as KeyEventArgs;
if (e != null && e.Key == Key.Enter)
this.InvokeActions(eventArgs);
}
}
引用程序集: System.Windows.Interactivity.dll
答案 1 :(得分:0)
找到解决方案:
在此answer之后,我们可以将焦点设置为由自定义属性IsFocused
控制。
因此,我将此属性置于按钮上,如果该属性位于第一行,则将该属性设置为true并绑定Enter InputBinding
public class ReferenceDossier : INotifyPropertyChanged
{
private bool _selected;
public bool Selected
{
get
{
return _selected;
}
set
{
_selected = value;
RaisePropertyChanged("Selected");
}
}
}
为第一条记录设置Selected
,以使第一行的按钮聚焦。
if(ReferenceDossiers.FirstOrDefault() != null)
ReferenceDossiers.First().Selected = true;
XAML
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="BorderThickness" Value="0"/>
</Style>
</DataGridTemplateColumn.CellStyle>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button behaviors:FocusExtension.IsFocused="{Binding Selected}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:MetroWindow}}, Path=DataContext.AddCommand}"
CommandParameter="{Binding}">
<Button.InputBindings>
<KeyBinding Key="Enter" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:MetroWindow}}, Path=DataContext.AddCommand}"
CommandParameter="{Binding}"/>
</Button.InputBindings>
<iconPacks:PackIconFontAwesome Kind="PlusCircle" Foreground="#FF94bf00"/>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
要通过上/下键选择其他行的按钮,我们应该自定义单元格,否则,CellTemplate
会集中在该按钮上,而ENTER键不起作用。