Domanda

Sono il rendering del testo utilizzando FormattedText, ma ci sembra essere un modo per eseguire la per-char hit testing sul output di rendering. E 'sola lettura, così ho praticamente solo bisogno di selezione, nessuna modifica.

userei RichTextBox o simili, ma ho bisogno di testo di output basato sul controllo codici incorporare nel testo stesso, in modo che non sempre il nido, il che rende la costruzione di elementi in linea di destra molto complessa. Sono anche un po 'preoccupato per le prestazioni di questa soluzione; Ho un gran numero di linee, e nuove linee vengono aggiunti spesso.

Ho guardato GlyphRun, sembra ho potuto ottenere hit-testing da esso o una classe correlato, ma sarei reimplementare un sacco di funzionalità, e sembra che ci dovrebbe essere un modo più semplice ...

Qualcuno sa di un buon modo per implementare questo?

È stato utile?

Soluzione

Il modo migliore è quello di progettare una buona struttura di dati per la memorizzazione e il testo che considera anche hit-testing. Un esempio potrebbe essere quello di dividere il testo in blocchi (parole, righe o paragrafi a seconda di che cosa avete bisogno). Poi ogni tale blocco dovrebbe avere un riquadro di delimitazione che deve essere ricalcolata in operazioni di formattazione. Considera anche posizioni Caret nel vostro disegno.

Una volta che si dispone di tale struttura diventa molto facile da fare hit-test, basta usare i riquadri di limitazione. Aiuterà anche nelle operazioni successive come evidenziando una particolare porzione di testo.

Altri suggerimenti

È possibile ottenere la geometria di ogni carattere da un oggetto FormattedText e utilizzare i limiti di ogni personaggio per fare il test di successo.

var geometry = (GeometryGroup)((GeometryGroup)text.BuildGeometry(new Point(0, 0))).Children[0];
foreach (var c in geometry.Children)
{
  if (c.Bounds.Contains(point))
    return index;
  index++;
}

In OnRender è possibile rendere questi oggetti della geometria, invece del testo formattato.

Completamente d'accordo con Sesh - il modo più semplice si sta andando a farla franca, non ri-attuazione di un intero carico di funzionalità FormattedText sta per essere suddividendo le singole voci si vuole colpire-test nei propri controlli / inline.

Si consiglia di utilizzare un TextBlock e l'aggiunta di ogni parola in quanto è proprio in linea (o), allora o si legano alla proprietà IsMouseDirectlyOver della linea, i nostri delegati aggiuntivi agli eventi MouseEnter & MouseLeave.

Se si vuole fare a livello di pixel hit testing dei glifi effettivi (cioè è il mouse esattamente il punto di questa 'i'), allora avrete bisogno di utilizzare GlyphRuns e fare hit testing manuale sui glifi ( leggi:. duro lavoro)

Sono molto in ritardo alla festa - se il partito non è finita, e non è necessario la geometria carattere effettivo, ho trovato qualcosa di simile utile:

 for (int i = 0; i < FormattedText.Text.Length; i++)
 {
            characterHighlightGeometry = FormattedText.BuildHighlightGeometry(new Point(), i, 1);
            CharacterHighlightGeometries.Children.Add(characterHighlightGeometry);
 }

BuildGeometry () include solo la geometria percorso effettivo di un carattere. BuildHighlightGeometry () genera i limiti esterni di tutti i personaggi - tra cui spazi, quindi un indice di uno spazio possono essere localizzati:

 foreach (var c in CharacterHighlightGeometries.Children)
        {
            if (c.Bounds.Contains(centerpoint))
            {
                q = c;
                cpos = index;
                break;
            }
            index++;
        }

Spero che questo aiuti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top