c# - punteros - formas del puntero del mouse en excel
haciendo una función de búsqueda simple, haciendo que el cursor salte(o resalte) la palabra que se busca (3)
Esto debería hacer el trabajo:
public bool DoSearch(RichTextBox richTextBox, string searchText, bool searchNext)
{
TextRange searchRange;
// Get the range to search
if(searchNext)
searchRange = new TextRange(
richTextBox.Selection.Start.GetPositionAtOffset(1),
richTextBox.Document.ContentEnd);
else
searchRange = new TextRange(
richTextBox.Document.ContentStart,
richTextBox.Document.ContentEnd);
// Do the search
TextRange foundRange = FindTextInRange(searchRange, searchText);
if(foundRange==null)
return false;
// Select the found range
richTextBox.Selection.Select(foundRange.Start, foundRange.End);
return true;
}
public TextRange FindTextInRange(TextRange searchRange, string searchText)
{
// Search the text with IndexOf
int offset = searchRange.Text.IndexOf(searchText);
if(offset<0)
return null; // Not found
// Try to select the text as a contiguous range
for(TextPointer start = searchRange.Start.GetPositionAtOffset(offset); start != searchRange.End; start = start.GetPositionAtOffset(1))
{
TextRange result = new TextRange(start, start.GetPositionAtOffset(searchText.Length);
if(result.Text == searchText)
return result;
}
return null;
}
El motivo del bucle for () en FindTextInRange. Desafortunadamente el rango. Text elimina los caracteres que no son de texto, por lo que en algunos casos el desplazamiento calculado por IndexOf será un poco demasiado bajo.
Ahora he usado demasiado tiempo, tratando de resolver un problema, que no pensé que sería tan difícil.
Aquí está el trato:
Estoy escribiendo una pequeña aplicación usando C # y WPF.
Tengo un RichTextBox que contiene un FlowDocument.
He agregado un pequeño cuadro de texto y un botón debajo de mi richtextbox.
El usuario luego teclea la palabra que desea buscar y presiona el botón.
El richtextbox saltará a la primera aparición de esa palabra.
es suficiente con que salte a la línea correcta, también puede seleccionar, resaltar o colocar el cursor por la palabra, cualquier cosa servirá, siempre que richTextBox se desplace a la palabra.
Continuando presionando el botón, saltará a la próxima aparición de la palabra, y así sucesivamente, hasta el final del documento.
Como dije, pensé que era una tarea simple, sin embargo estoy teniendo serios problemas para resolver esto.
He usado otro método. Esto busca la Palabra. (Por clic); Lo resalta y mueve el cursor a esa palabra.
// Search text and Highlight it (Per Click)
// Manually add the "FindText"
public int FindText(string txtToSearch, int searchStart, int searchEnd)
{
// Unselect the previously searched string
if (searchStart > 0 && searchEnd > 0 && IndexOfSearchText >= 0)
{ rtb.Undo(); }
// Set the return value to -1 by default.
int retVal = -1;
// A valid starting index should be specified.
// if indexOfSearchText = -1, the end of search
if (searchStart >= 0 && IndexOfSearchText >= 0)
{
// A valid ending index
if (searchEnd > searchStart || searchEnd == -1)
{
// Find the position of search string in RichTextBox
IndexOfSearchText = rtb.Find(txtToSearch, searchStart, searchEnd, RichTextBoxFinds.None);
// Determine whether the text was found in richTextBox1.
if (IndexOfSearchText != -1)
{
// Return the index to the specified search text.
retVal = IndexOfSearchText;
}
}
}
return retVal;
}
// Button to Perform the Search (By Click)
private void btn_Search_Click(object sender, EventArgs e)
{
int startIndex = 0;
if (txt_Search.Text.Length > 0) startIndex = FindText(txt_Search.Text.Trim(), start, rtb.Text.Length);
// If string was found in the RichTextBox, highlight it
if (startIndex >= 0)
{
int x = rtb.Find(txt_Search.Text);
rtb.SelectionStart = x;
rtb.Focus();
// Set the highlight color as red
rtb.SelectionBackColor = Color.LightYellow; // Remove to prevent Minor Bug
rtb.SelectionColor = Color.Black; // Remove to prevent Minor Bug
// Find the end index. End Index = number of characters in textbox
int endindex = txt_Search.Text.Length;
// Highlight the search string
rtb.Select(startIndex, endindex);
// mark the start position after the position of
// last search string
start = startIndex + endindex;
}
}
// TextBox used for Searching
private void txt_Search_TextChanged(object sender, EventArgs e)
{
start = 0;
IndexOfSearchText = 0;
}
}
}
Espero que esto ayude
Esta es una variante que encontrará el fósforo más cercano a la posición de Caret .
private TextRange FindText(string findText)
{
var fullText = DoGetAllText();
if (string.IsNullOrEmpty(findText) || string.IsNullOrEmpty(fullText) || findText.Length > fullText.Length)
return null;
var textbox = GetTextbox();
var leftPos = textbox.CaretPosition;
var rightPos = textbox.CaretPosition;
while (true)
{
var previous = leftPos.GetNextInsertionPosition(LogicalDirection.Backward);
var next = rightPos.GetNextInsertionPosition(LogicalDirection.Forward);
if (previous == null && next == null)
return null; //can no longer move outward in either direction and text wasn''t found
if (previous != null)
leftPos = previous;
if (next != null)
rightPos = next;
var range = new TextRange(leftPos, rightPos);
var offset = range.Text.IndexOf(findText, StringComparison.InvariantCultureIgnoreCase);
if (offset < 0)
continue; //text not found, continue to move outward
//rtf has broken text indexes that often come up too low due to not considering hidden chars. Increment up until we find the real position
var findTextLower = findText.ToLower();
var endOfDoc = textbox.Document.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);
for (var start = range.Start.GetPositionAtOffset(offset); start != endOfDoc; start = start.GetPositionAtOffset(1))
{
var result = new TextRange(start, start.GetPositionAtOffset(findText.Length));
if (result.Text?.ToLower() == findTextLower)
{
return result;
}
}
}
}
Si desea resaltar la coincidencia, sería tan simple como cambiar este método a vacío y hacer esto cuando encuentre la coincidencia:
textbox.Selection.Select(result.Start, result.End);