解决WPF的TextBox的复制、剪切功能被其他应用程序妨碍的问题

在一些应用程序运行时,它会使WPF的TextBox的复制、剪切功能发生错误,我遇到的情况是会卡顿并且无法成功执行。听说这个问题是由多个应用程序同时访问剪切板导致的。我现在分享临时的解决方法,但是我会尽量避免使用这个方法,似乎它会造成应用不定期崩溃的问题。我会建议用户关闭制造障碍的应用程序,因为利用管理者的漏洞去制造损失是恶行。

因为使用 Clipboard.SetDataObject() 能避免这个问题,因此只要把TextBox自带的复制、剪切功能关闭,再用代码来实现就可以解决。

关闭TextBox自带的复制、剪切功能的代码,在XAML文件中:

<TextBox PreviewKeyDown="keyFunctionForCommonTextBox">
<TextBox.CommandBindings>
 <!--关闭自带的复制功能-->
<CommandBinding Command="ApplicationCommands.Copy" CanExecute="CommandBinding_CanExecute" />
<!--关闭自带的剪切功能-->
<CommandBinding Command="ApplicationCommands.Cut" CanExecute="CommandBinding_CanExecute" />
</TextBox.CommandBindings>
</TextBox>

相关的C#代码:

//使用快捷键来实现复制或剪切。
private void keyFunctionForCommonTextBox(object sender, KeyEventArgs e)
{
if ((e.KeyboardDevice.IsKeyDown(Key.LeftCtrl) || e.KeyboardDevice.IsKeyDown(Key.RightCtrl)))
{
if (e.Key == Key.C)
{
((TextBox)sender).copySelectText();
return;
}
else if (e.Key == Key.X)
{
((TextBox)sender).cutSelectText();
return;
}
}
}

//关闭自带的功能。
private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
e.Handled = true;
}

实现鼠标右键菜单的复制、剪切、粘贴功能的代码,在XAML文件中:

<TextBox PreviewKeyDown="keyFunctionForCommonTextBox">
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Header="复制" Click="textBoxCopyContent" />
<MenuItem Header="剪切" Click="textBoxCutContent" />
<MenuItem Header="粘贴" Click="textBoxPasteContent" />
</ContextMenu>
</TextBox.ContextMenu>

相关的C#代码:

private void textBoxCopyContent(object sender, RoutedEventArgs e)
{
MenuItem _menuItem = (MenuItem)sender;
ContextMenu _contextMenu = (ContextMenu)_menuItem.Parent;
TextBox _textBox = (TextBox)_contextMenu.PlacementTarget;
_textBox.copySelectText();
}

private void textBoxCutContent(object sender, RoutedEventArgs e)
{
MenuItem _menuItem = (MenuItem)sender;
ContextMenu _contextMenu = (ContextMenu)_menuItem.Parent;
TextBox _textBox = (TextBox)_contextMenu.PlacementTarget;
_textBox.cutSelectText();
}

private void textBoxPasteContent(object sender, RoutedEventArgs e)
{
MenuItem _menuItem = (MenuItem)sender;
ContextMenu _contextMenu = (ContextMenu)_menuItem.Parent;
TextBox _textBox = (TextBox)_contextMenu.PlacementTarget;
_textBox.paste();
}

 为TextBox添加扩展方法,需要放在一个静态类中:

public static class extendWPF
{

public static void copySelectText(this TextBox p_textBox)
{
if (p_textBox.SelectedText.Length < 1)
{
return;
}
Clipboard.SetDataObject(p_textBox.SelectedText);
}

public static void cutSelectText(this TextBox p_textBox)
{
if (p_textBox.SelectedText.Length < 1)
{
return;
}
Clipboard.SetDataObject(p_textBox.SelectedText);
int _position = p_textBox.SelectionStart;
string _text = p_textBox.Text.Substring(0, _position);
_text = _text + p_textBox.Text.Substring(_position + p_textBox.SelectionLength);
p_textBox.Text = _text;
p_textBox.Select(_position, 0);
}

public static void paste(this TextBox p_textBox)
{
int _position = p_textBox.CaretIndex;
if (p_textBox.SelectionLength < 1)
{
string _result = p_textBox.Text.Substring(0, p_textBox.CaretIndex);
_result = _result + Clipboard.GetText();
int _length = Clipboard.GetText().Length;
_result = _result + p_textBox.Text.Substring(p_textBox.CaretIndex);
p_textBox.Text = _result;
p_textBox.CaretIndex = _position + _length;
}
else
{
string _result = p_textBox.Text.Substring(0, p_textBox.SelectionStart);
_result = _result + Clipboard.GetText();
int _length = Clipboard.GetText().Length;
_result = _result + p_textBox.Text.Substring(p_textBox.SelectionStart+p_textBox.SelectionLength);
p_textBox.Text = _result;
p_textBox.CaretIndex = _position + _length;
}
}

}
posted @ 2022-12-31 22:59  和风拥抱  阅读(916)  评论(0)    收藏  举报