Question

Quelle serait une bonne approche pour afficher et modifier une grande quantité de texte non formaté (comme le fait le bloc-notes) à l'aide de WPF? Le chargement d'une grosse chaîne dans une zone de texte empêche l'interface utilisateur de répondre. Les performances globales sont loin d’être comparables aux contrôles TextBox des frameworks Microsoft UI précédents.

Quelles options ai-je pour résoudre ce problème? Je ne veux pas bloquer le thread d'interface utilisateur pendant que le contrôle de texte charge le texte. J'aurais peut-être besoin d'une sorte de " virtualisation " car ce n’est peut-être pas une bonne idée de charger tout le texte dans le contrôle (je suppose que 20 Mo de texte créeraient beaucoup de glyphes même s’ils ne sont pas visibles). Il semble que TextBox n’ait même plus de méthode AppenText (), donc je n’ai même pas le moyen de contrôler le chargement asynchrone du texte.

N’est-ce pas un problème commun? Il semble que WPF ne fournisse rien pour cela hors de la boîte. Pourquoi cela est-il ainsi?

Était-ce utile?

La solution

AvalonEdit, l'éditeur de texte dans SharpDevelop, a été entièrement écrit à partir de zéro dans WPF et est optimisé pour de grandes quantités de texte. Il ne prend pas en charge le texte enrichi (bien qu’il prenne en charge la coloration syntaxique et d’autres fonctionnalités intéressantes telles que le pliage). Je pense que cela conviendrait parfaitement à votre facture.

Voici un article sur l'éditeur écrit par le développeur:

http://www.codeproject.com/KB/edit/AvalonEdit.aspx

Autres conseils

Le problème est que la zone de texte est un élément conteneur unique. Les contrôles de liste, tels que ListBox, virtualisent très bien en raison du recyclage des conteneurs. Il n’ya vraiment rien de simple à faire pour accélérer la zone de texte.

Mais le contrôle TextBox a une méthode AppendText ():

        TextBox tb = new TextBox();
        tb.AppendText("Hello");

Alors oui, vous pouvez l'utiliser pour ajouter de façon dynamique du texte, comme vous l'avez mentionné.

Vous pouvez simplement utiliser une zone de texte avec un style qui donne à l'utilisateur plus d'espace pour afficher le texte. Il existe probablement des commandes plus avancées de Telerik et d'autres, mais si vous n'avez pas besoin d'options d'édition, cela devrait suffire.

Vous pouvez toujours associer des technologies: vous pouvez déposer une zone de texte WinForms sur un parent WPF. Vous perdez des choses comme le style, l'opacité, l'animation, les transformations, etc., mais si tout ce qui compte est de modifier du texte, la zone de texte WinForms le fait très bien.

Avez-vous essayé le WPF RichTextBox ? Vous voudrez certainement lire les informations sur FlowDocument si vous suivez cette voie.

Vous pouvez utiliser FlowDocument , mais cela ne fonctionne pas immédiatement pour établir une liaison avec la propriété Document d'un FlowDocument dans MVVM. .

Une autre solution consiste à utiliser FlowDocumentScrollViewer et à établir une liaison avec sa propriété Document .

(ou vous pouvez même utiliser un FlowDocumentReader et lier sa propriété Document , similaire au FlowDocumentScrollViewer . Cela vous donne une interface utilisateur différente. )

La vue:

 <FlowDocumentScrollViewer Document="{Binding FlowDocument, Mode=OneWay}" />

Le modèle de vue:

   FlowDocument fd = new FlowDocument();
        Paragraph p = new Paragraph();
        Run r = new Run();
        r.Text = "large text";
        p.Inlines.Add(r);
        fd.Blocks.Add(p);
        FlowDocument = fd;

 private FlowDocument _FlowDocument;
    public FlowDocument FlowDocument
    {
      get{ return _FlowDocument; }
      set
      {
        _FlowDocument = value;
        NotifyOfPropertyChange(nameof(FlowDocument));
      }
    }

Voir aussi ceci pour des conseils de performance supplémentaires: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-text#flowdocument-textblock-and-label-controls

Pourquoi ne pas essayer quelque chose comme ceci:

Conservez toute la chaîne en mémoire, mais n'en affichez qu'une "tranche" dans la zone de texte. La taille de la chaîne coupée en tranches serait calculée dynamiquement en fonction de la taille de la zone de texte, de la taille de la police, etc.

Bien sûr, cela implique beaucoup de code non trivial pour un affichage, une synchronisation, etc. corrects, mais cela semble être la voie à suivre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top