De toute façon pour faire un WPF textblock sélectionnable?
Je veux rendre le texte affiché dans la Plein d'esprit, Twitter open source client, au choix. Il est actuellement affichée à l'aide d'un custom textblock. J'ai besoin d'utiliser un TextBlock parce que je travaille avec le textblock est inlines pour afficher et mettre en forme le nom d'utilisateur @et les liens que des liens hypertexte. Une demande fréquente est d'être en mesure de copier-coller le texte. Pour ce faire j'ai besoin de faire le TextBlock sélectionnable.
J'ai essayé de le faire fonctionner en affichant le texte à l'aide d'une lecture seule zone de texte dessiné pour ressembler à un textblock, mais cela ne fonctionne pas dans mon cas car une zone de texte n'a pas inlines. En d'autres termes, je ne peux pas le style ou le format du texte dans une zone de texte individuellement comme je peux avec un TextBlock.
Des idées?
- Je vais essayer d'utiliser le contrôle RichTextBox pour voir si ça va fonctionner. Mais à partir de l'expérience antérieure avec le richtextbox est beaucoup plus impliqué.
- Avez-vous pensé à utiliser un FlowDocumentScrollViewer, avec un FlowDocument contenant des Paragraphes et de l'Exécution? -- Cela fonctionne assez bien pour moi quand j'ai besoin d'sélectionnable, et chaque Paragraphe et peut être de style séparément.
- Après avoir essayé quelques solutions de contournement ci-dessous, FlowDocumentScrollViewer était la voie à suivre. Il semble occuper une utile à mi-chemin entre RichTextBox et TextBlock.
Vous devez vous connecter pour publier un commentaire.
Ici toutes les réponses sont juste en utilisant un
TextBox
ou d'essayer de mettre en œuvre la sélection de texte manuellement, ce qui conduit à une mauvaise exécution ou non-natif comportement (clignotant signe àTextBox
, pas de prise en charge du clavier dans le manuel des implémentations etc.)Après des heures de creuser autour et la lecture de la WPF code source, j'ai plutôt découvert une façon de permettre à la WPF natif de la sélection de texte pour
TextBlock
contrôles (ou vraiment tout les autres contrôles). La plupart des fonctionnalités autour de la sélection de texte est mis en œuvre dansSystem.Windows.Documents.TextEditor
système de classe.Pour permettre la sélection de texte pour votre contrôle, vous devez faire deux choses:
Appel
TextEditor.RegisterCommandHandlers()
une fois à la classe de registreles gestionnaires d'événements
Créer une instance de
TextEditor
pour chaque instance de votre classe et de passer à l'instance sous-jacente de votreSystem.Windows.Documents.ITextContainer
àIl existe aussi une exigence que votre commande est
Focusable
propriété est définie àTrue
.Ce que c'est! Cela semble facile, mais malheureusement
TextEditor
classe est marquée comme interne. Donc j'ai dû écrire une réflexion wrapper autour d'elle:J'ai également créé un
SelectableTextBlock
dérivé deTextBlock
qui prend les étapes ci-dessus:Une autre option serait de créer une propriété attachée pour
TextBlock
pour permettre la sélection de texte sur la demande. Dans ce cas, désactiver la sélection de nouveau, on a besoin de détacher uneTextEditor
à l'aide de la réflexion équivalent de ce code:Run
éléments et même conserve la mise en forme lors de la copieHyperlink
dans leTextBlock
...qu'il va jeter unExecutionEngineException
.TextBlock
a intégréHyperlink
s tant que laHyperlink
n'est pas le dernier en ligne dans il. L'ajout d'une fuite de videRun
le contenu des correctifs quel que soit le problème sous-jacent est que les résultats dans leExecutionEngineException
être jeté.TextTrimming="CharacterEllipsis"
sur leTextBlock
et la largeur disponible est insuffisante, si vous déplacez le pointeur de la souris sur la ..., il se bloque avec le Système.ArgumentException a Demandé "la distance est à l'extérieur le contenu du document associé." au Système.De Windows.Documents.TextPointer.InitializeOffset(TextPointer position, Int32 distance, LogicalDirection direction) 🙁 Ne sait pas si il y a une solution autre que de laisser TextTrimming défini sur Aucun.J'ai pu trouver aucun exemple de vraiment répondre à la question. Toutes les réponses ont utilisé une zone de texte ou de RichTextbox. J'ai besoin d'une solution qui m'a permis d'utiliser un TextBlock, et c'est la solution que j'ai créé.
Je crois que la bonne façon de le faire est d'étendre le TextBlock classe. C'est le code que j'ai utilisé pour étendre le TextBlock classe pour me permettre de sélectionner le texte et le copier dans le presse-papiers. "sdo" est l'espace de noms de référence que j'ai utilisé dans le WPF.
WPF à l'Aide de longues Catégorie:
Code Derrière pour la Classe Étendue:
Exemple Le Code De La Fenêtre:
Appliquer ce style à votre zone de texte et c'est tout (inspiré de cet article):
Créer ControlTemplate pour TextBlock et de mettre une zone de texte à l'intérieur avec de propriété readonly ensemble.
Ou tout simplement utiliser la zone de texte et en faire lecture seule, vous pouvez modifier la zone de texte.Style afin qu'il ressemble à TextBlock.
Je ne suis pas sûr si vous pouvez faire un TextBlock sélectionnable, mais une autre option serait d'utiliser un RichTextBox - c'est comme une zone de texte comme vous l'avez suggéré, mais prend en charge la mise en forme que vous souhaitez.
Selon Centre De Développement Windows:
TextBlock ne dispose pas d'un modèle. Donc, afin de parvenir à cela, nous avons besoin d'utiliser une zone de texte dont le style est modifié pour se comporter comme un textBlock.
Alors que la question n'dire "Sélectionnable" je crois que le intentionnelle des résultats est de mettre le texte dans le presse-papiers. Cela peut facilement et élégamment être obtenue par l'ajout d'un Menu Contextuel et l'élément de menu appelé copie qui met le Textblock Text valeur de la propriété dans le presse-papiers. Juste une idée de toute façon.
Il existe une solution alternative qui pourrait être adaptable à la RichTextBox oultined dans ce post de blog - il utilisé un déclencheur pour changer de modèle de contrôle lors de l'utilisation plane sur le contrôle, ce qui devrait aider avec les performances
J'ai mis en place SelectableTextBlock dans mon opensource bibliothèque de contrôles. Vous pouvez l'utiliser comme ceci:
L'ajout de @torvin réponse et @Dave Huang mentionné dans les commentaires si vous avez
TextTrimming="CharacterEllipsis"
permis l'application se bloque lorsque vous passez la souris sur les points de suspension.J'ai essayé d'autres options mentionnées dans le fil sur l'utilisation d'une zone de texte, mais ça ne semble pas être la solution car il ne montre pas les "points de suspension" et aussi, si le texte est trop long pour tenir le récipient en sélectionnant le contenu du champ de texte "parchemins" interne qui n'est pas un TextBlock comportement.
Je pense que la meilleure solution est @torvin de la réponse, mais on a le méchant crash lorsque vous passez la souris sur les points de suspension.
Je sais que ce n'est pas joli, mais l'abonnement/désabonnement à l'interne pour les exceptions non gérées et de la manipulation de l'exception était la seule façon que j'ai trouvée pour résoudre ce problème, merci de partager si quelqu'un a une meilleure solution 🙂
J'apporte quelques petites modifications