2009-04-07 32 views
9

Estoy trabajando en una aplicación de chat simple. Actualmente los mensajes son encuadernados a un cuadro de lista personalizada de estilo como esto (XAML simplificado):Mostrar imágenes en TextBlock (WPF)

<ListBox ItemsSource="{Binding MessageCollection}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Text}"/> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Ahora me gustaría ser capaz de poner imágenes (como emoticonos gráficos) en el texto del mensaje que se muestra. ¿Hay alguna forma de lograr esto usando TextBlock (o cualquier otro componente estándar) o necesito usar algún control especial para esto?

Gracias de antemano

Respuesta

1

Si desea que las imágenes realmente dentro del texto (como un icono gestual), entonces van a tener que hacer algún trabajo. Esto suena como una de las pocas veces que realmente quisiera un control de usuario, el punto de que sería uno que escanea el texto buscando valores de emoticones y construyendo una plantilla de datos sobre la marcha.

Recuerde que cualquier cosa que se puede hacer en XAML se puede hacer en el código, por lo que el código que estoy pensando seguiría esta idea general:

  1. texto escaneado para valores emoticon y crear una lista de valores para los datos elementos.
  2. Crea un DockPanel.
  3. Foreach elemento en la lista, agregar ya sea un TextBlock o una imagen (basado en el valor).
  4. Establezca este contenido en el DockPanel.

Creo que algo como esto es realmente lo que estás buscando, pero si solo quieres una imagen, entonces la sugerencia de ValueConverter funcionaría.

+0

me gusta esto, suena bastante simple. Pero estoy preocupado por el envoltorio de texto ... Trataré de implementarlo y ver cómo funciona. Gracias. – lacop

+0

Ese es un buen punto. Es posible que necesite hacer algunas mediciones y dividir el texto según sea necesario para obtener el efecto de ajuste correcto. Solo debería ser un problema cuando hay un emoticón presente. –

+0

De todos modos, parece que no puedo encontrar una manera de hacer esto. Creé un control de usuario personalizado, pero no sé cómo anular el mecanismo de representación y reemplazarlo con mi código que emite elementos TextBox/Image, según sea necesario. ¿Me puede dar una pista, por favor? – lacop

1

Se puede usar un convertidor de valores para convertir el texto a otro tipo que tiene una lista de segmentos que se componen de texto o la cara sonriente (en el orden en el que aparecen).

Luego, puede usar una plantilla de datos para enlazar a ese nuevo tipo y mostrar el texto y las caras sonrientes de manera apropiada.

+0

Podría explicar la segunda parte un poco más (o simplemente vincularme a docs/sample). Creo que entiendo la primera parte, pero no sé cómo asignar dos tipos de datos diferentes a diferentes elementos. – lacop

-1

Utilice el elemento Imagen en lugar del Bloque de texto y use un Convertidor para asignar el valor del texto a la imagen de la sonrisa.

<ListBox ItemsSource="{Binding MessageCollection}"> 
<ListBox.ItemTemplate> 
    <DataTemplate> 
     <Image Source="{Binding Text, Converter={StaticResource MyImageConverter}}"/> 
    </DataTemplate> 
</ListBox.ItemTemplate> 

+0

Pero esto solo permitirá una imagen en el mensaje, ¿verdad? Lo que quiero es una combinación de texto e imágenes en un mensaje. – lacop

+0

DataTemplace puede ser todo lo que desee. Por ejemplo < ... otros controles ...> ema

3

El contenido de un TextBlock siempre es solo una serie de Inlines, por lo que debe usar InlineUIContainer. Puede insertar este contenedor como una de las líneas en su TextBlock donde quiera que aparezca una imagen, alternando con el texto Ejecuciones. Puede analizar un mensaje y, al mismo tiempo, seguir agregando los tokens (texto o imágenes) que encuentre en la colección Inlines del TextBlock.

31

Simplemente use InlineUIContainer.

<TextBlock TextWrapping="Wrap"> 
    <Run>Some text.</Run> 
    <InlineUIContainer> 
     <Image Source="http://sstatic.net/stackoverflow/img/apple-touch-icon.png" Height="20"></Image> 
    </InlineUIContainer> 
    <Run>Some more text.</Run> 
</TextBlock> 
1

También me encontré con este problema hace poco y puedo superar esto mediante

Creación de un cuadro de lista ItemTemplate que contiene un ItemsControl que tiene un WrapPanel en el ItemsPanelTemplate y luego ligar mi cadena a la ItemsSource de ItemsControl con un IValueConverter que alberga toda la lógica.

Divida sus palabras y busque/busque en sus emoticones cadenas, hipervínculos, etc. y cree su TextBlock, Imagen, Hipervínculo, Elementos de botón y configure sus valores y controladores de eventos.

En la función, cree una lista < UIElement> y llene la lista con los controles que ha generado y devuelva la lista como el objeto en la función Convert del IValueConverter.

Como tiene el WrapPanel allí, se realiza la envoltura.

Cuestiones relacionadas