WPF 用户控件中的复制和粘贴






4.31/5 (5投票s)
准备一个 WPF 用户控件,使其能够接受剪贴板命令。
引言
当我尝试创建一个能够自行接收剪贴板命令的用户控件时,这个问题让我困惑了很长时间。基本的 XAML 设置很简单。
<UserControl x:Class="UserControlCommands.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
>
<UserControl.CommandBindings>
<CommandBinding Command="Paste" Executed="CommandBinding_PasteExecuted"/>
<CommandBinding Command="Copy" Executed="CommandBinding_CopyExecuted"/>
</UserControl.CommandBindings>
</UserControl>
然而,什么也没发生。commandbinding
不会触发,因为命令只会路由到具有焦点的 UI 元素。而且,如你所见,usercontrol
内部没有任何元素能够获得焦点(例如,一个 TextBox
对象)。
我找到的第一个提示是设置用户控件属性 Focusable="true"
。但这本身并没有帮助,用户控件仍然无法在点击时获得焦点。在添加 IsTabStop="true"
后,我至少能够通过 Tab 键进入用户控件——现在,在按下 CTRl+C 或 CTRL+V 时,事件会触发,无需任何额外操作(Copy
和 Paste
是 ApplicationCommands
枚举的枚举器,因此应用程序能够自动引发它们)。
然而,这仍然不够。我希望用户控件通过鼠标点击获得焦点,然后能够将信息粘贴到其中,认为一定存在可以在 XAML 中设置的某个属性或类似的东西。结果却并非如此。但我找到了一个关于完全相反主题的讨论
虽然我不喜欢这种方法(认为一定有完全在 XAML 中实现的方法),但我还是妥协了,并添加了一个 MouseDown
事件,调用 this.Focus()
。然后,只剩下最后一步:UI 元素需要一个背景才能接收鼠标点击,所以我设置了 background="aquamarine"
。
最终。这是完整的示例
XAML
<UserControl x:Class="UserControlCommands.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
IsTabStop="True"
MouseDown="UserControl_MouseDown"
Focusable="True"
Background="Aquamarine"
>
<UserControl.CommandBindings>
<CommandBinding Command="Paste" Executed="CommandBinding_Executed"/>
<CommandBinding Command="Copy" Executed="CommandBinding_Executed"/>
</UserControl.CommandBindings>
</UserControl>
代码后置
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace UserControlCommands
{
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Clipboard operation occured!");
}
private void UserControl_MouseDown(object sender, MouseButtonEventArgs e)
{
this.Focus();
}
}
}