/// <devdoc> /// Overload to allow for passing the text when the mask is being changed from null, /// in this case the maskedTextProvider holds backend info only (not the text). /// </devdoc> private void SetMaskedTextProvider( MaskedTextProvider newProvider, string textOnInitializingMask ) { Debug.Assert( newProvider != null, "Initializing from a null MaskProvider ref." ); // Set R/W properties. newProvider.IncludePrompt = this.maskedTextProvider.IncludePrompt; newProvider.IncludeLiterals = this.maskedTextProvider.IncludeLiterals; newProvider.SkipLiterals = this.maskedTextProvider.SkipLiterals; newProvider.ResetOnPrompt = this.maskedTextProvider.ResetOnPrompt; newProvider.ResetOnSpace = this.maskedTextProvider.ResetOnSpace; // If mask not initialized and not initializing it, the new provider is just a property backend. // Change won't have any effect in text. if( this.flagState[IS_NULL_MASK] && textOnInitializingMask == null) { this.maskedTextProvider = newProvider; return; } int testPos = 0; bool raiseOnMaskInputRejected = false; // Raise if new provider rejects old text. MaskedTextResultHint hint = MaskedTextResultHint.NoEffect; MaskedTextProvider oldProvider = this.maskedTextProvider; // Attempt to add previous text. // If the mask is the same, we need to preserve the caret and character positions if the text is added successfully. bool preserveCharPos = oldProvider.Mask == newProvider.Mask; // Cache text output text before setting the new provider to determine whether we need to raise the TextChanged event. string oldText; // NOTE: Whenever changing the MTP, the text is lost if any character in the old text violates the new provider's mask. if( textOnInitializingMask != null ) // Changing Mask (from null), which is the only RO property that requires passing text. { oldText = textOnInitializingMask; raiseOnMaskInputRejected = !newProvider.Set( textOnInitializingMask, out testPos, out hint ); } else { oldText = TextOutput; // We need to attempt to set the input characters one by one in the edit positions so they are not // escaped. int assignedCount = oldProvider.AssignedEditPositionCount; int srcPos = 0; int dstPos = 0; while( assignedCount > 0 ) { srcPos = oldProvider.FindAssignedEditPositionFrom( srcPos, forward ); Debug.Assert( srcPos != MaskedTextProvider.InvalidIndex, "InvalidIndex unexpected at this time." ); if (preserveCharPos) { dstPos = srcPos; } else { dstPos = newProvider.FindEditPositionFrom(dstPos, forward); if (dstPos == MaskedTextProvider.InvalidIndex) { newProvider.Clear(); testPos = newProvider.Length; hint = MaskedTextResultHint.UnavailableEditPosition; break; } } if( !newProvider.Replace( oldProvider[srcPos], dstPos, out testPos, out hint )) { preserveCharPos = false; newProvider.Clear(); break; } srcPos++; dstPos++; assignedCount--; } raiseOnMaskInputRejected = !MaskedTextProvider.GetOperationResultFromHint(hint); } // Set provider. this.maskedTextProvider = newProvider; if( this.flagState[IS_NULL_MASK] ) { this.flagState[IS_NULL_MASK] = false; } // Raising events need to be done only after the new provider has been set so the MTB is in a state where properties // can be queried from event handlers safely. if( raiseOnMaskInputRejected ) { OnMaskInputRejected(new MaskInputRejectedEventArgs(testPos, hint)); } if( newProvider.IsPassword ) { // Reset native edit control so the MaskedTextBox will take control over the characters that // need to be replaced with the password char (the input text characters). // MTB takes over. SetEditControlPasswordChar('\0'); } EventArgs e = EventArgs.Empty; if (textOnInitializingMask != null /*changing mask from null*/ || oldProvider.Mask != newProvider.Mask) { OnMaskChanged(e); } SetWindowText(GetFormattedDisplayString(), oldText != TextOutput, preserveCharPos); }
public void ToString_PasswordTest () { MaskedTextProvider mtp; mtp = new MaskedTextProvider ("####"); mtp.PasswordChar = '*'; Assert.AreEqual ("____", mtp.ToString (true, true, true, 0, mtp.Length), "#A1"); Assert.AreEqual ("____", mtp.ToString (false, true, true, 0, mtp.Length), "#A2"); mtp.Add ("314"); Assert.AreEqual ("314_", mtp.ToString (true, true, true, 0, mtp.Length), "#B1"); Assert.AreEqual ("***_", mtp.ToString (false, true, true, 0, mtp.Length), "#B2"); mtp.Clear (); mtp.InsertAt ("666", 1); Assert.AreEqual ("_666", mtp.ToString (true, true, true, 0, mtp.Length), "#C1"); Assert.AreEqual ("_***", mtp.ToString (false, true, true, 0, mtp.Length), "#C2"); }