Comment autoriser TextBlock
la sélection du texte de?
J'ai essayé de le faire fonctionner en affichant le texte en utilisant une TextBox en lecture seule de style ressemblant à un bloc de texte, mais cela ne fonctionnera pas dans mon cas car une TextBox n'a pas de ligne. En d'autres termes, comment le rendre sélectionnable?
Réponses:
Utilisez
TextBox
plutôt un avec ces paramètres pour le rendre en lecture seule et pour ressembler à unTextBlock
contrôle.la source
Toutes les réponses ici utilisent simplement un
TextBox
ou essaient d'implémenter la sélection de texte manuellement, ce qui conduit à de mauvaises performances ou à un comportement non natif (caret clignotantTextBox
, pas de prise en charge du clavier dans les implémentations manuelles, etc.)Après des heures à fouiller et à lire le code source WPF , j'ai découvert un moyen d'activer la sélection de texte WPF native pour les
TextBlock
contrôles (ou vraiment tout autre contrôle). La plupart des fonctionnalités de sélection de texte sont implémentées dans laSystem.Windows.Documents.TextEditor
classe système.Pour activer la sélection de texte pour votre contrôle, vous devez faire deux choses:
Appelez
TextEditor.RegisterCommandHandlers()
une fois pour enregistrer les gestionnaires d'événements de classeCréer une instance de
TextEditor
chaque instance de votre classe et passer l'instance sous - jacente de votreSystem.Windows.Documents.ITextContainer
à elleIl est également nécessaire que la
Focusable
propriété de votre contrôle soit définie surTrue
.Ça y est ...! Cela semble facile, mais malheureusement, la
TextEditor
classe est marquée comme interne. J'ai donc dû écrire un wrapper de réflexion autour de lui:J'ai également créé un
SelectableTextBlock
dérivé deTextBlock
qui prend les étapes indiquées ci-dessus:Une autre option serait de créer une propriété jointe pour
TextBlock
permettre la sélection de texte à la demande. Dans ce cas, pour désactiver à nouveau la sélection, il faut détacher unTextEditor
en utilisant l'équivalent de réflexion de ce code:la source
TextBlock
a intégréHyperlink
s tant que leHyperlink
n'est pas la dernière ligne en elle. L'ajout d'un vide de finRun
au contenu corrige quel que soit le problème sous-jacent qui entraîne leExecutionEngineException
rejet.TextTrimming="CharacterEllipsis"
sur leTextBlock
et que la largeur disponible est insuffisante, si vous déplacez le pointeur de la souris sur le…, il se bloque avec System.ArgumentException "La distance demandée est en dehors du contenu du document associé." à System.Windows.Documents.TextPointer.InitializeOffset (position TextPointer, distance Int32, direction LogicalDirection) :( Je ne sais pas s'il existe une solution de contournement autre que de laisser TextTrimming défini sur Aucun.Je n'ai trouvé aucun exemple de réponse à la question. Toutes les réponses ont utilisé une Textbox ou une RichTextbox. J'avais besoin d'une solution qui me permettait d'utiliser un TextBlock, et c'est la solution que j'ai créée.
Je pense que la bonne façon de procéder consiste à étendre la classe TextBlock. C'est le code que j'ai utilisé pour étendre la classe TextBlock pour me permettre de sélectionner le texte et de le copier dans le presse-papiers. "sdo" est la référence d'espace de noms que j'ai utilisée dans le WPF.
WPF utilisant la classe étendue:
Code derrière pour la classe étendue:
Exemple de code de fenêtre:
la source
Appliquez ce style à votre TextBox et c'est tout (inspiré de cet article ):
la source
Créez ControlTemplate pour le TextBlock et placez un TextBox à l'intérieur avec le jeu de propriétés en lecture seule. Ou utilisez simplement TextBox et rendez-le en lecture seule, puis vous pouvez modifier TextBox.Style pour qu'il ressemble à TextBlock.
la source
Je ne sais pas si vous pouvez rendre un TextBlock sélectionnable, mais une autre option serait d'utiliser un RichTextBox - c'est comme un TextBox comme vous l'avez suggéré, mais prend en charge la mise en forme que vous souhaitez.
la source
Selon Windows Dev Center :
la source
Bien que la question dise «sélectionnable», je crois que les résultats intentionnels sont d'obtenir le texte dans le presse-papiers. Cela peut être facilement et élégamment réalisé en ajoutant un menu contextuel et un élément de menu appelé copie qui place la valeur de la propriété Textblock Text dans le presse-papiers. Juste une idée de toute façon.
la source
TextBlock n'a pas de modèle. Donc, pour y parvenir, nous devons utiliser un TextBox dont le style est modifié pour se comporter comme un textBlock.
la source
Il existe une solution alternative qui pourrait être adaptable à la RichTextBox oultined dans ce billet de blog - il a utilisé un déclencheur pour échanger le modèle de contrôle lorsque l'utilisation survole le contrôle - devrait aider avec les performances
la source
la source
Ajout à la réponse de @ torvin et comme @Dave Huang l'a mentionné dans les commentaires si vous avez
TextTrimming="CharacterEllipsis"
activé l'application se bloque lorsque vous survolez les points de suspension.J'ai essayé d'autres options mentionnées dans le fil de discussion sur l'utilisation d'un TextBox mais cela ne semble vraiment pas être la solution non plus car il n'affiche pas les «points de suspension» et aussi si le texte est trop long pour s'adapter au conteneur en sélectionnant le contenu de la zone de texte "défile" en interne, ce qui n'est pas un comportement TextBlock.
Je pense que la meilleure solution est la réponse de @ torvin mais a le méchant crash lors du survol des ellipses.
Je sais que ce n'est pas joli, mais l'abonnement / le désabonnement en interne aux exceptions non gérées et la gestion de l'exception ont été le seul moyen que j'ai trouvé pour résoudre ce problème, veuillez partager si quelqu'un a une meilleure solution :)
la source
J'ai implémenté SelectableTextBlock dans ma bibliothèque de contrôles opensource. Vous pouvez l'utiliser comme ceci:
la source
J'apporte quelques petites modifications
la source
la source