/// <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); }
/// <devdoc> /// Override version to be able to perform the operation on a cloned provider. /// </devdoc> private bool PlaceChar(MaskedTextProvider provider, char ch, int startPosition, int length, bool overwrite, out MaskedTextResultHint hint) { Debug.Assert( !this.flagState[IS_NULL_MASK], "This method must be called when a Mask is provided." ); this.caretTestPos = startPosition; if (startPosition < this.maskedTextProvider.Length) { if (length > 0) // Replacing selection with input char. { int endPos = startPosition + length - 1; return provider.Replace(ch, startPosition, endPos, out this.caretTestPos, out hint); } else { if (overwrite) { // overwrite character at next edit position from startPosition (inclusive). return provider.Replace(ch, startPosition, out this.caretTestPos, out hint); } else // insert. { return provider.InsertAt(ch, startPosition, out this.caretTestPos, out hint); } } } hint = MaskedTextResultHint.UnavailableEditPosition; return false; }
public void ReplaceTest () { MaskedTextProvider mtp; int Int32_out; MaskedTextResultHint resultHint; mtp = new MaskedTextProvider ("00aa"); mtp.Add ("11zz"); Assert.AreEqual (true, mtp.Replace ("2x", 1, 2, out Int32_out, out resultHint), "#A1"); Assert.AreEqual (2, Int32_out, "#A2"); Assert.AreEqual (MaskedTextResultHint.Success, resultHint, "#A3"); MaskedTextProviderTest.AssertProperties (mtp, "ReplaceTest_A", 3, true, false, 4, 0, CultureInfo.GetCultureInfo ("es-ES"), 4, true, false, false, 3, 4, @"00aa", true, true, '\x0', '\x5F', true, true, true, @"12xz", @"12xz", @"12xz", @"12xz", @"12xz", @"12xz", @"12xz"); mtp = new MaskedTextProvider ("aaaaaaaaaaaaaaa"); mtp.Add ("abcdefghijk"); Assert.AreEqual (true, mtp.Replace ("ZZ", 2, 6, out Int32_out, out resultHint), "#B1"); Assert.AreEqual (3, Int32_out, "#B2"); Assert.AreEqual (MaskedTextResultHint.Success, resultHint, "#B3"); MaskedTextProviderTest.AssertProperties (mtp, "ReplaceTest_B", 3, true, false, 8, 7, CultureInfo.GetCultureInfo ("es-ES"), 15, true, false, false, 7, 15, @"aaaaaaaaaaaaaaa", true, false, '\x0', '\x5F', true, true, true, @"abZZhijk", @"abZZhijk", @"abZZhijk", @"abZZhijk_______", @"abZZhijk_______", @"abZZhijk", @"abZZhijk"); mtp = new MaskedTextProvider ("aaaaaaaaaaaaaaa"); mtp.Add ("abcdefghijk"); Assert.AreEqual (true, mtp.Replace ('Z', 2, 6, out Int32_out, out resultHint), "#C1"); Assert.AreEqual (2, Int32_out, "#C2"); Assert.AreEqual (MaskedTextResultHint.Success, resultHint, "#C3"); MaskedTextProviderTest.AssertProperties (mtp, "ReplaceTest_C", 3, true, false, 7, 8, CultureInfo.GetCultureInfo ("es-ES"), 15, true, false, false, 6, 15, @"aaaaaaaaaaaaaaa", true, false, '\x0', '\x5F', true, true, true, @"abZhijk", @"abZhijk", @"abZhijk", @"abZhijk________", @"abZhijk________", @"abZhijk", @"abZhijk"); // Replacing over a space. // This causes the replacement character to be INSERTED at the first edit position. // only for Replace (string, *), not for Replace (char, *). mtp = new MaskedTextProvider ("a aaa"); mtp.Add ("123"); Assert.AreEqual (true, mtp.Replace ("4", 1, 1, out Int32_out, out resultHint), "#D1"); Assert.AreEqual (MaskedTextResultHint.Success, resultHint, "#D3"); Assert.AreEqual (2, Int32_out, "#D2"); MaskedTextProviderTest.AssertProperties (mtp, "ReplaceTest_D", 3, true, false, 4, 0, CultureInfo.GetCultureInfo ("es-ES"), 4, true, false, false, 4, 5, @"a aaa", true, true, '\x0', '\x5F', true, true, true, @"1 423", @"1 423", @"1 423", @"1 423", @"1423", @"1 423", @"1423"); }
private bool PlaceCharCore( MaskedTextProvider provider, char ch, int startPosition, int length, bool overwrite, out int caretPosition ) { caretPosition = startPosition; if( startPosition < m_maskedTextProvider.Length ) { MaskedTextResultHint notUsed; if( length > 0 ) { int endPosition = ( startPosition + length ) - 1; return provider.Replace( ch, startPosition, endPosition, out caretPosition, out notUsed ); } if( overwrite ) return provider.Replace( ch, startPosition, out caretPosition, out notUsed ); return provider.InsertAt( ch, startPosition, out caretPosition, out notUsed ); } return false; }
public void Replace_string_int_int_int_MaskedTextResultHintTestException () { MaskedTextProvider mtp = new MaskedTextProvider ("a"); int th; MaskedTextResultHint rh; mtp.Replace (null, 1, 2, out th, out rh); }