如何撤消由绑定引起的文本框文本更改?
我有一个 TextBox
,我绑定了一个字符串,如果我现在手动编辑文本,我将能够通过 TextBox.Undo()
撤消这些更改,但是如果我更改字符串并更新 TextBox 的文本,我无法撤消这些更改,并且 TextBox.CanUndo
属性将始终为 false
。
我想这可能与文本的完全替换而不是修改有关。
关于如何让它发挥作用有什么想法吗?
I have a TextBox
to which i bound a string, if i now edit the text manually i will be able to undo those changes via TextBox.Undo()
, if however i change the string and the TextBox's text is updated, i cannot undo those changes and the TextBox.CanUndo
property will always be false
.
I suppose this might have to do with the complete replacement of the text rather than a modification of it.
Any ideas on how i can get this to work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我遇到了同样的问题(需要在 Enter 上接受输入并在 Escape 上恢复为原始值),并且能够以这种方式处理它:
UpdateSourceTrigger< /code> 将
TextBox.Text
绑定到Explicit
。处理 TextBox 的
KeyDown
事件并将以下代码放入其中:我发现这个解决方案非常优雅,因为它也可以在 DataTemplates 中使用。例如,在我的例子中,我使用它来允许就地编辑列表框项目。
I was facing the same issue (needed to accept input upon Enter and revert to original value upon Escape) and was able to handle it this way:
UpdateSourceTrigger
of yourTextBox.Text
binding toExplicit
.Handle
KeyDown
event of your TextBox and put the following code in there:I found this solution to be very elegant because it can be used in DataTemplates too. For example in my case I used it to allow in-place editing of ListBox items.
好的,开始发表评论并意识到这是一个答案:)
TextBox.Undo() 旨在撤消用户与文本框的交互,而不是其绑定到的属性中的值更改。文本框绑定的属性的更改只会更新文本框的值,这与用户通过焦点/键盘编辑不同。如果您需要撤消对绑定属性的更改,您可能需要研究向应用程序添加撤消/重做堆栈。
OK, started to leave a comment and realized it was an answer :)
TextBox.Undo() is intended to undo a user's interaction with the text box not a value change in the property it's bound to. A change in the property the text box is bound to will just update the value of the TextBox, this is a different change than a user edit via focus/keyboard. If you need to Undo changes to your bound properties you probably need to investigate adding an Undo/Redo stack to your application.
直接分配给文本框:
Assign directly to the TextBox:
如果更改的应用方式看起来像是来自用户,则文本框会将更改应用到内部撤消堆栈,如下所示:
这是一个糟糕的解决方法,因为它会杀死用户在剪贴板上的所有内容(恢复这里悲观地讨论了其中的问题: 我该怎么办在 C# 中备份和恢复系统剪贴板?),但我认为尽管如此,还是值得发布的。
The TextBox will apply the changes to the internal undo stack if they are applied in such a way that they appear to have come from the user, like so:
It's a terrible workaround, as it kills whatever the user has on the clipboard (the restoring of which is pessimistically discussed here: How do I backup and restore the system clipboard in C#?) but I thought it might be worth having posted nonetheless.
因此,我认为 ViewModel 撤消/重做文章是一篇很好的文章,但它既介绍了 ViewModel 模式,也介绍了如何编写自定义撤消/重做功能。另外,为了回应confusedGeek,我认为可能存在这样的示例:撤消模型中的更改,而不仅仅是单个控件中的更改是适当的(假设您有一个文本框和一个滑块都绑定到示例属性,您想要撤消更改)无论是哪个控件创建的,因此我们讨论的是应用程序级别撤消而不是控件级别)。
因此,这里是一个简单的(如果不是有点笨拙的)示例,它使用 CommandBinding 和简单的撤消堆栈精确执行您所要求的操作:
这是 XAML:
在此示例中,行为与典型的 TextBox 撤消行为略有不同,因为 1 )我忽略了选择,并且 2)我没有将多个击键分组为单个撤消步骤,这两件事都是您在实际应用程序中需要考虑的事情,但自己实现起来应该相对简单。
So, I think the ViewModel Undo/Redo article is a good one, but it's as much as about the ViewModel pattern as it is about how to write custom Undo/Redo functionality. Also, in response to confusedGeek, I think there could be examples where undoing changes in your model, not just in your individual controls is appropriate (say you had a textbox and a slider both bound to the sample property, you want to undo a change regardless of which control made it, so we're talking about app level undo instead of control level).
So given that, here is a simple, if not somewhat kludgey example of doing precisely what you ask using a CommandBinding and a simplistic undo stack:
And here is the XAML:
In this example the behavior is slightly different than typical TextBox undo behavior because 1) I'm ignoring selection, and 2) I'm not grouping multiple keystrokes into a single undo step, both of which are things you would want to consider in a real app, but should be relatively straightforward to implement yourself.