Editar: He descubierto en una respuesta diferente que el TextBlock
también tiene una colección Inlines
a la que se puede agregar Run
s. Anvaka's answer ingeniosamente utiliza una propiedad adjunta como una especie de convertidor.
Tuve algunas ideas sobre cómo abordar esto. Solo uno manejaría el ajuste de palabras correctamente y manejaría ejecuciones de caracteres con diferentes fuentes.
Usa un FlowDocumentScrollViewer
y ata la cuerda con un ValueConverter
que convierte la cadena en FlowDocument
.
<FlowDocumentScrollViewer
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
Document="{Binding MyString, Converter={StaticResource MyConverter}}" />
Puede crear propiedades en el convertidor para establecer las propiedades de letra normal, que no pueden ser establecidas en la FlowDocumentScrollViewer
y tiene que ser establecido en el FlowDocument
que crea el convertidor. Probablemente también necesite algunas propiedades de Fuente para las subcadenas de excepción que necesitan una Fuente diferente (y posiblemente un tamaño diferente). Otra opción es crear Binding
s en el FlowDocument
para algunas de esas propiedades (RelativeSource
).
Y así es como se crea un FlowDocument
en código:
FlowDocument doc = new FlowDocument();
doc.FontFamily = new FontFamily("Our Own Font");
Paragraph par = new Paragraph();
doc.Blocks.Add(par);
A continuación, tendrá que dividir la cadena entrante en las subseries especiales, manteniendo intactas las subcadenas. Tendrá que hacer rodar su propio divisor y tener una colección de subcadenas en el convertidor o ser suministradas al convertidor.
Añadir una subcadena normal al párrafo:
Run r = new Run(substring);
par.Inlines.Add(r);
Añadir una subcadena especial al párrafo con una fuente diferente:
Run r = new Run(substring);
r.FontFamily = new FontFamily("Arial");
par.Inlines.Add(r);
Los anteriores son sólo pequeños fragmentos. No sé cómo quieres acercarte a dividir la cadena o iterar sobre las subcadenas ya que no estoy familiarizado con los datos, así que no proporcioné el método que utilicé solo para ver si mi idea funcionaría. También puede usar Dictionary
para detectar una subcadena y usar un reemplazo en la salida, como detectar "(SM)"
y reemplazarlo por "℠"
.
Deseo saber si tiene alguna pregunta o si hay algo que pueda detallar.
(Es bueno que usted ha dicho que es de sólo lectura. Un RichTextBox
no funcionaría porque su propiedad Document
no es un DependencyProperty
y por lo tanto no puede ser el objetivo de un Binding
. Aunque, uno puede ser capaz de utilizar Mode=OneWayToSource
revertirla, la implementación de ConvertBack
en lugar de Convert
.)
"creo que lo que dejó fuera (iteración en la cadena y la creación de esas carreras) es la parte difícil."
De hecho, fui muy breve sobre la división de la secuencia en las subcadenas especiales. Cuando dije: "No sé cómo dividirás la cadena", no estaba diciendo que no tenía ni idea de cómo hacerlo (lo reformulé), pero que no tenía idea de cómo querrías. para manejarlo Supuse que no sería difícil para usted descifrar esa parte porque es el tipo de problema de manipulación de cuerdas que los posibles contratistas averiguarían. Eso, y es posible que descubras casos límite entre tus datos que requieren cambios en la forma en que lo manejas.
Le describiré una versión relativamente cruda utilizando IndexOf()
y Substring()
.
Así que aquí está el problema-dentro-del-problema: tiene muchas cadenas (por ejemplo, "Company Name(R), makers of Product(TM)"
) que contienen 0 o más subcadenas especiales. Estas subcadenas son pocas y conocidas, y la cadena de entrada debe dividirse en varias cadenas donde las subcadenas especial y no especial se han aislado una de otra (por ejemplo, {"Company Name", "(R)", ", makers of Product", "(TM)"}
).
Las subcadenas especiales son pocas y conocidas, por lo que necesita una serie de ellas. Usted sabe por el valor de retorno de .IndexOf()
si encontró una subcadena o no. Al recorrer las subcadenas especiales conocidas, puede encontrar la primera instancia de cualquiera de ellas con una comparación de índices, también dejando de lado la longitud de la subcadena.
Cada vez que se encuentre la subcadena más temprano especial en la cadena S
(si lo hay), se hace derivar cadenas A
, B
y C
. B
es la subcadena especial, A
y C
son el antes y el después. Adjunte A
y B
a List
y C
se convierte en el nuevo S
y lo vuelve a hacer. Excepto cuando no encuentre ninguna subcadena especial en S
y no esté vacía, en cuyo caso solo la adjuntará.
Ahora, cada cadena de índice impar en List
es una subcadena especial. Es posible que desee consultar mi mención de un Dictionary
en la parte anterior de esta respuesta para usar como una búsqueda para agregar un Run
de "℠"
cuando la subcadena que encontró fue "(SM)"
.
¿Puede decirnos más sobre esta fuente (nombre? Propio o comercial?) Y ¿por qué no puede usar una fuente diferente? –
Es una fuente interna personalizada; no puede usar uno diferente porque debería pasar por un largo proceso de aprobación. El cliente es muy grande, y creo que tendríamos problemas para rastrear quién lo creó. – SergioL