WPF TextBox에 이벤트 붙여 넣기
상속하는 사용자 지정 컨트롤을 만들었습니다 TextBox
. 이 사용자 지정 컨트롤은 숫자 TextBox
이며 숫자 만 지원합니다.
OnPreviewTextInput
문자가 유효한 입력인지 확인하기 위해 입력되는 각 새 문자를 확인 하는 데 사용 하고 있습니다. 이것은 훌륭하게 작동합니다. 나는에 텍스트를 붙여 넣을 경우에는 TextBox
, OnPreviewTextInput
해고되지 않습니다.
에 붙여 넣은 텍스트를 캡처하는 가장 좋은 방법은 무엇입니까 TextBox
?
또한 백 스페이스를 눌렀을 때 문제가 발생하여 어떤 이벤트가 발생하는지 알 수 없습니다. OnPreviewTextInput
해고되지 않습니다!
WPF에서 붙여 넣은 텍스트 및 백 스페이스 이벤트를 캡처하는 방법에 대한 아이디어가 TextBox
있습니까?
필요한 경우를 대비하여 몇 가지 코드가 있습니다. 당신을 도울 수 있습니다.
public Window1()
{
InitializeComponent();
// "tb" is a TextBox
DataObject.AddPastingHandler(tb, OnPaste);
}
private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
var isText = e.SourceDataObject.GetDataPresent(DataFormats.UnicodeText, true);
if (!isText) return;
var text = e.SourceDataObject.GetData(DataFormats.UnicodeText) as string;
...
}
TextBox.Text 속성을 변경할 수있는 모든 개별 이벤트를 가로 채고 트랩하려고 할 때 발생하는 문제는 이러한 이벤트가 많이 있다는 것입니다.
- TextInput : 사용자 유형
- KeyDown : 삭제, 백 스페이스, Enter, IME
- 명령 제스처 : Ctrl-X, Ctrl-Y, Ctrl-V, Ctrl-X
- MouseDown : 붙여 넣기 버튼, 잘라 내기 버튼, 실행 취소 버튼, ...
- 클릭 : 붙여 넣기, 잘라 내기, 실행 취소 버튼에 로컬 포커스가있을 때 스페이스 바를 누름
- RaiseEvent : 코드에서 붙여 넣기, 잘라 내기, 실행 취소, 다시 실행 명령 발생
- 접근성 : 음성 명령, 점자 키보드 등
이 모든 것을 확실하게 가로채는 것은 헛된 일입니다. 훨씬 더 나은 해결책은 TextBox.TextChanged를 모니터링하고 원하지 않는 변경 사항을 거부하는 것입니다.
이 답변 에서는 요청되는 특정 시나리오에 대해 TextBoxRestriction 클래스를 구현하는 방법을 보여줍니다. 이 동일한 기술을 TextBox 컨트롤에 적용하려는 제한과 함께 사용하도록 일반화 할 수 있습니다.
예를 들어, 귀하의 경우 해당 코드 RestrictValidChars
의 RestrictDeleteTo
속성 과 유사한 연결된 속성을 구현할 수 있습니다 . 내부 루프가 삭제가 아닌 삽입을 확인한다는 점을 제외하면 동일합니다. 다음과 같이 사용됩니다.
<TextBox my:TextBoxRestriction.RestrictValidChars="0123456789" />
이것은 어떻게 처리 될 수 있는지에 대한 아이디어입니다. 원하는 것에 따라 코드를 구조화하는 방법에는 여러 가지가 있습니다. 예를 들어 대리자 또는 이벤트가 포함 된 개체를 사용하는 연결된 속성을 사용하여 유효성을 검사하는 자체 코드를 호출하도록 TextBoxRestriction을 변경할 수 있습니다.
TextBoxRestriction 클래스를 사용할 때 Text 속성을 바인딩하는 방법에 대한 자세한 내용은 다른 답변을 참조하여 원하지 않을 때 제한을 트리거하지 않습니다.
백 스페이스의 경우 PreviewKeyDown 이벤트 를 확인하십시오.
붙여 넣기 명령의 경우 ApplicationCommands.Paste에 명령 바인딩을 추가하고 아무것도하지 않으려면 인수를 handled로 설정합니다.
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Paste"
Executed="PasteExecuted" />
</Window.CommandBindings>
그리고 코드 뒤에 :
private void PasteExecuted(object sender, ExecutedRoutedEventArgs e)
{
e.Handled = true;
}
PreviewKeyDown
이벤트와 TextChanged
이벤트로 이를 달성 할 수 있습니다 .
에서 PreviewKeyDown
캡처 붙여 넣기 작업
if(Key.V == e.Key && Keyboard.Modifiers == ModifierKeys.Control)
{
strPreviousString = this.txtNumber.Text;
bIsPasteOperation = true;
}
에서 TextChanged
이벤트
if (true == bIsPasteOperation)
{
if (false == this.IsNumber(this.txtNumber.Text))
{
this.txtNumber.Text = strPreviousString;
e.Handled = true;
}
bIsPasteOperation = false;
}
어디 IsNumber
방법의 유효성을 검사 입력 된 텍스트는 번호인지 아닌지
private bool IsNumber(string text)
{
int number;
//Allowing only numbers
if (!(int.TryParse(text, out number)))
{
return false;
}
return true
}
이것은 나를 위해 꽤 잘 작동합니다. 사용자가 내용을 변경할 때 텍스트 상자의 색상을 변경하고 싶었습니다.
- 마침표 및 음수 문자를 포함한 숫자 허용
- keys typed: delete, backspace, ctrl-V (paste), ctrl-X (cut)
- right mouse click for paste and cut
I was able to achieve it with the 3 events below:
public bool IsDirty {
set {
if(value) {
txtValue.Background = Brushes.LightBlue;
} else {
txtValue.Background = IsReadOnly ? Brushes.White : Brushes.LightYellow;
}
}
get {
return txtValue.Background == Brushes.LightBlue;
}
}
private void PreviewTextInput(object sender, TextCompositionEventArgs e) {
TextBox tb = ((TextBox)sender);
string originalText = tb.Text;
string newVal = "";
//handle negative
if (e.Text=="-") {
if(originalText.IndexOf("-") > -1 || tb.CaretIndex != 0 || originalText == "" || originalText == "0") {
//already has a negative or the caret is not at the front where the - should go
//then ignore the entry
e.Handled = true;
return;
}
//put it at the front
newVal = e.Text + originalText;
} else {
//normal typed number
newVal = originalText + e.Text;
}
//check if it's a valid double if so then dirty
double dVal;
e.Handled = !double.TryParse(newVal, out dVal);
if(!e.Handled) {
IsDirty = true;
}
}
private void PreviewKeyUp(object sender, KeyEventArgs e) {
//handle paste
if ((Key.V == e.Key || Key.X == e.Key) && Keyboard.Modifiers == ModifierKeys.Control) {
IsDirty = true;
}
//handle delete and backspace
if (e.Key == Key.Delete || e.Key == Key.Back) {
IsDirty = true;
}
}
private void PreviewExecuted(object sender, ExecutedRoutedEventArgs e) {
//handle context menu cut/paste
if (e.Command == ApplicationCommands.Cut || e.Command == ApplicationCommands.Paste) {
IsDirty = true;
}
}
참고URL : https://stackoverflow.com/questions/3061475/paste-event-in-a-wpf-textbox
'IT박스' 카테고리의 다른 글
Assert.AreNotEqual과 Assert.AreNotSame의 차이점은 무엇입니까? (0) | 2020.11.30 |
---|---|
CSS는 개발 환경과 웹 서버에서 다르게 렌더링됩니다. (0) | 2020.11.30 |
Visual Studio 솔루션에서 모든 중단 점 지우기 (0) | 2020.11.30 |
동적 파이썬 객체를 json으로 변환 (0) | 2020.11.30 |
GDB 디버깅 세션을 자동화하는 가장 좋은 방법은 무엇입니까? (0) | 2020.11.30 |