积极答复者
关于WFP TextBox控件输入中文的问题

问题
-
RT:今天在做一个用户名输入限制的时候在对TextBox控件的Text输入做限制的时候发现再输入中文的标点符号是 TextBox控件的PreviewTextInput事件和TextBoxChanged事件的引发顺序出现问题并且会报出一个错误。这个错误的引发应该是在TextBoxChange事件里面所写函数出现的,就是对TextBox.Text重新赋值时出现的。不知道为什么会这样,请大神帮忙看看。。。。。。。
未处理 System.InvalidOperationException
Message=无法关闭撤消单元,因为不存在已打开的单元。
Source=PresentationFramework
StackTrace:
在 MS.Internal.Documents.UndoManager.Close(IParentUndoUnit unit, UndoCloseAction closeAction)
在 System.Windows.Documents.ImmComposition.CloseCompositionUndoUnit(UndoCloseAction undoCloseAction, ITextPointer compositionEnd)
在 System.Windows.Documents.ImmComposition.UpdateCompositionText(FrameworkTextComposition composition, Int32 resultLength, Boolean includeResultText, ITextPointer& start, ITextPointer& end)
在 System.Windows.Documents.ImmComposition.RaiseTextInputStartEvent(FrameworkTextComposition composition, Int32 resultLength, String compositionString)
在 System.Windows.Documents.ImmComposition.OnWmImeChar(IntPtr wParam, Boolean& handled)
在 System.Windows.Documents.ImmComposition.ImmCompositionFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
在 System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
在 MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
在 MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
在 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
在 System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
在 MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
在 MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
在 MS.Win32.HwndSubclass.DefWndProcWrapper(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
在 MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
在 MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
在 MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
在 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
在 System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
在 System.Windows.Application.RunDispatcher(Object ignore)
在 System.Windows.Application.RunInternal(Window window)
在 System.Windows.Application.Run(Window window)
在 System.Windows.Application.Run()
在 LiveChainCHIS_Client.App.Main() 位置 D:\项目\LiveChainCHIS-Client\LiveChainCHIS-Client\obj\x86\Debug\App.g.cs:行号 0
在 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
InnerException:补充说明一下 ,这个错误只出现于 数据绑定后的TextBox控件上,也不知道是为什么!
- 已编辑 三十三级台风 2012年12月17日 7:04
答案
-
首先你例子有些问题,
1)你设置textBox.Text = textBox.Text.Remove(offset, change[0].AddedLength);,会导致TextChanged事件再触发一次。
2)你说的绑定不会起作用,因为后台你Text=。。。 这样的赋值语句会让绑定自动断掉的。
Sheldon _Xiao
MSDN Community Support | Feedback to us
Develop and promote your apps in Windows Store
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- 已标记为答案 Sheldon _XiaoModerator 2013年1月2日 7:25
全部回复
-
把你这两个事件中的代码贴一下。
我自己做了一个小的demo 发出来大家看看吧!
xaml
<TextBox Height="88" HorizontalAlignment="Left" Margin="221,38,0,0" TextChanged="textBox1_TextChanged" Name="textBox1"
Text="{Binding MyText,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="303" />
cs
this.textBox1.DataContext = new testBase();
public class testBase : INotifyPropertyChanged
{
private string myText;
public string MyText
{
get { return myText; }
set
{
myText = value;
this.RaisePropertyChanged("MyText");
}
}
public void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
var textBox = sender as TextBox;
TextChange[] change = new TextChange[e.Changes.Count];
e.Changes.CopyTo(change, 0);
int offset = change[0].Offset;
bool isvalidation = false;
if (change[0].AddedLength > 0)
{
isvalidation = !Regex.IsMatch(textBox.Text, @"^\w*$");
textBox.Text = textBox.Text.Remove(offset, change[0].AddedLength);
textBox.Select(offset, 0);
}
}在TextBox里面输入中文的标点符号 就会报错。输入英文或者英文标点符号没有任务问题。
这样报出来的错误提示和我在项目中的不太一样,不过都提到了 {"无法关闭撤消单元,因为不存在已打开的单元。"} 这个问题。
- 已编辑 三十三级台风 2012年12月17日 7:29
-
绑定了,完全抄的你得代码,而且 UndoLimit 的值是 -1。
根据你提到的这个属性,我使用了 Ctrl + z 来测试,int offset = change[0].Offset; 会报错,因为 change 的元素为 0,
然后我按照你提示的将 UndoLimit 设置为 0 ,上述错误消失。
因此,你得错可能是由你的输入法或你的代码触发了Ctrl+z操作所致。
- 已编辑 三十三级台风 2012年12月17日 8:48
-
首先你例子有些问题,
1)你设置textBox.Text = textBox.Text.Remove(offset, change[0].AddedLength);,会导致TextChanged事件再触发一次。
2)你说的绑定不会起作用,因为后台你Text=。。。 这样的赋值语句会让绑定自动断掉的。
Sheldon _Xiao
MSDN Community Support | Feedback to us
Develop and promote your apps in Windows Store
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- 已标记为答案 Sheldon _XiaoModerator 2013年1月2日 7:25