我已经设置了ListBox
这样的:
<ListBox ItemsSource="{Binding Logs, Mode=OneWay}" x:Name="logListView">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=.}">
<TextBlock.InputBindings>
<KeyBinding Key="C"
Modifiers="Ctrl"
Command="Copy"/>
</TextBlock.InputBindings>
<TextBlock.CommandBindings>
<CommandBinding Command="Copy"
Executed="KeyCopyLog_Executed"
CanExecute="CopyLog_CanExecute"/>
</TextBlock.CommandBindings>
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Command="Copy">
<MenuItem.CommandBindings>
<CommandBinding Command="Copy"
Executed="MenuCopyLog_Executed"
CanExecute="CopyLog_CanExecute"/>
</MenuItem.CommandBindings>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
如您所见,在模板中,每个模板TextBlock
都有一个允许用户复制文本的上下文菜单.这有效.
还有TextBlock
一个KeyBinding
to ctrl+c和a CommandBinding
复制.当我按下ctrl+c方法时KeyCopyLog_Executed
没有执行.我已经检查过调试器.
我应该如何绑定密钥TextBlock
?
Pav*_*kov 12
这里有几个问题.
首先,KeyBindings
只有当前聚焦元素位于定义KeyBindings的元素内时才会起作用.在你的情况下,你有一个ListBoxItem
焦点,但KeyBindings
在子元素上定义 - TextBlock
.因此,定义KeyBindings
一个TextBlock
不会在任何情况下工作,因为一个TextBlock不能接收焦点.
其次,您可能需要知道要复制的内容,因此需要将当前选定的日志项作为参数传递给Copy
命令.
此外,如果您ContextMenu
在TextBlock
元素上定义一个元素,只有在右键单击时才会打开它TextBlock
.如果单击列表项的任何其他部分,它将无法打开.因此,您需要ContextMenu
在列表框项目本身上定义.
考虑到所有这些,我认为你想要做的事情可以通过以下方式完成:
<ListBox ItemsSource="{Binding Logs, Mode=OneWay}"
x:Name="logListView"
IsSynchronizedWithCurrentItem="True">
<ListBox.InputBindings>
<KeyBinding Key="C"
Modifiers="Ctrl"
Command="Copy"
CommandParameter="{Binding Logs/}" />
</ListBox.InputBindings>
<ListBox.CommandBindings>
<CommandBinding Command="Copy"
Executed="CopyLogExecuted"
CanExecute="CanExecuteCopyLog" />
</ListBox.CommandBindings>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Command="Copy"
CommandParameter="{Binding}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
在这里,我们定义了一个KeyBinding
对ListBox
自身及指定为CommandParameter
当前选择的列表框项目(日志项).
CommandBinding
也在该ListBox
级别定义,它是右键单击菜单和键盘快捷键的单个绑定.
在ContextMenu
我们的风格定义ListBoxItem
绑定,并CommandParameter
通过此表示的数据项ListBoxItem
(日志条目).
该DataTemplate
只是声明了一个TextBlock
具有约束力的当前数据项.
最后,Copy
代码隐藏中只有一个命令处理程序:
private void CopyLogExecuted(object sender, ExecutedRoutedEventArgs e) {
var logItem = e.Parameter;
// Copy log item to the clipboard
}
private void CanExecuteCopyLog(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = true;
}
Run Code Online (Sandbox Code Playgroud)
感谢 Pavlov Glazkov 解释说按键和命令绑定需要处于级别ListBox
,而不是项目模板级别。
这是我现在的解决方案:
<ListBox ItemsSource="{Binding Logs, Mode=OneWay}">
<ListBox.InputBindings>
<KeyBinding Key="C"
Modifiers="Ctrl"
Command="Copy"/>
</ListBox.InputBindings>
<ListBox.CommandBindings>
<CommandBinding Command="Copy"
Executed="KeyCopyLog_Executed"
CanExecute="CopyLog_CanExecute"/>
</ListBox.CommandBindings>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=.}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Command="Copy">
<MenuItem.CommandBindings>
<CommandBinding Command="Copy"
Executed="MenuCopyLog_Executed"
CanExecute="CopyLog_CanExecute"/>
</MenuItem.CommandBindings>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
哪里KeyCopyLog_Executed
:
private void KeyCopyLog_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
{
if ((sender as ListBox).SelectedItem != null)
{
LogItem item = (LogItem) (sender as ListBox).SelectedItem;
Clipboard.SetData("Text", item.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
并且MenuCopyLog_Executed
是:
private void MenuCopyLog_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
{
LogItem item = (LogItem) ((sender as MenuItem).TemplatedParent as ContentPresenter).DataContext;
Clipboard.SetData("Text", item.ToString());
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6739 次 |
最近记录: |