2009-04-30 14 views
6

WPF kullanarak büyük miktarda biçimlendirilmemiş metni (notepade gibi) görüntülemek ve düzenlemek için iyi bir yaklaşım ne olurdu? Bir TextBox içine büyük bir dize yükleme UI yanıt vermiyor. Genel performans, önceki Microsoft Kullanıcı Arabirimi Çerçevelerinin TextBox Denetimleriyle neredeyse karşılaştırılamaz.WPF'de büyük miktarda metni nasıl işlerim/düzenlerim?

Bu sorunu çözmek için hangi seçenekleri kullanmalıyım? Metin denetimi metni yüklerken UI iş parçacığı engellemek istemiyorum. Ayrıca bir çeşit "sanallaştırma" ye de ihtiyacım olabilir çünkü tüm metni kontrole yüklemek iyi bir fikir olmayabilir (sanırım 20MB metin, görünür olmasalar bile çok fazla glif oluşturabilir). TextBox'ın artık bir AppenText() Yöntemi bile olmadığı görünüyor, bu yüzden metnin eşzamansız yüklenmesini kontrol etmenin bir yolu bile yok.

Bu yaygın bir sorun değil mi? WPF'nin bu kutunun dışında bir şey sağlamadığı görülüyor. Bu neden böyle?

+0

Sadece biraz oynamıştım. Sorun, kaydırma bölgesini hesaplamakla ilgili bir şey gibi görünüyor. Kaydırma çubuğunu devre dışı bırakırsanız, sorun şu şekilde gider - ctrl + sonunu (ve altını veya bir şeyi hesaplamak zorunda kalmazsanız) hte metin kutusunun içerik şablonu bir scrollviewer olur. Belki de sorunun scrollviewer'ı optimize etmede daha fazlası vardır. Cevap değil, belki bir ipucu? – JMarsch

cevap

1

SharpDevelop'taki metin editörü AvalonEdit, WPF'de tamamen sıfırdan yazılmıştır ve büyük miktarlarda metin için optimize edilmiştir. Zengin metni desteklemez (söz dizimi vurgulama ve katlama gibi diğer harika özellikleri desteklemesine rağmen). Bunun faturanıza mükemmel şekilde uyduğunu düşünüyorum.İşte

geliştirici tarafından yazılan editör ilgili bir makale:

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

+1

Kendi metin denetiminizi yazmanın muhtemelen en iyi çözüm olduğu sonucuna vardım. Yine de biraz üzücü. – bitbonk

+3

-1. AvalonEdit'i 4MB veya daha büyük dosyaları korkunç sonuçlarla kullandım. Son derece buggy ve benim app deli bir bombardıman gibi çöküyor. – code4life

+1

Yeni bir VS WPF C# projesi oluşturdum, NuGet AvalonEdit.Sample paketini ekleyin, StartupUri'yi değiştirin, çalıştırın ve voila !, AvalonEdit uygulaması düzgün çalışıyor. TextBlock 22 saniye sürerken, bir saniyede 8k satırlı bir 4MB metin dosyası açıldı. Kesinlikle TextBlock için bir yedek olabilir. –

1

Metin kutusuna, metni görüntülemek için kullanıcıya daha fazla alan sağlayan bir stil kullanabilirsiniz. Telerik ve diğerlerinden muhtemelen daha gelişmiş denetimler vardır, ancak yeterli olması gereken düzenleme seçeneklerine gerek yoktur.

bellekte tüm dizeyi tutun ama metin kutusuna bunun sadece bir 'dilim' gösterir: Böyle bir şey çalışıyorum nereden

+0

Burada asıl sorun, performans ve kullanılabilirliktir. Metin denetimi metni yüklerken UI iş parçacığını engellemek istemiyorum, ayrıca bir tür "sanallaştırma" ye ihtiyacım olabilir çünkü tüm metni kontrole yerleştirmek iyi bir fikir olmayabilir (20MB metin çok gliflerin). – bitbonk

+0

Bu durumda üçüncü taraf kontrolüyle giderdim. Ekstra biçimlendirme özelliklerini kaldırabilir ve Not Defteri gibi basit tutabilirsiniz. Bir üçüncü taraf kontrolü, bahsettiğiniz metin miktarlarını daha iyi ele alabilmelidir. Metni başka bir iş parçacığına da yükleyebilir ve yüklendikten sonra kontrole bağlayabilirsiniz. – Lukasz

-1

. Bu dilimlenmiş dizgenin boyutu, metin kutusunun boyutuna, yazı tipi boyutuna vb. Bağlı olarak dinamik olarak hesaplanacaktır.

Elbette bu, düzgün görüntüleme, eşitleme vb. Için çok fazla önemsiz bir kod içerir. gitmek.

1

Teknolojileri her zaman karıştırabilir ve eşleştirebilirsiniz: Bir WinForms TextBox'ı bir WPF ebeveyine bırakabilirsiniz. Stil, opaklık, animasyon, dönüşüm vb. Gibi şeyleri kaybedersiniz, ancak tüm önemli olan metin düzenliyorsa, WinForms TextBox bunu yapar.

+0

Bu üzücü, ama muhtemelen en iyi seçenek. – bitbonk

3

Bu yardımcı olup olmadığından emin değilim, ancak FlowDocumentPageViewer ve FlowDocumentReader kullanmayı denediniz mi?

Ayrıca, çok iyi ek açıklamaları desteği vardır ve belgeleri metin biçiminde yüklemek için ideal görünüyor.

2

Sorun, TextBox'un tek bir kapsayıcı öğesi olmasıdır. ListBox gibi liste kontrolleri, konteyner geri dönüşümü nedeniyle çok iyi bir şekilde sanallaştırır. TextBox'u hızlandırmak için yapabileceğiniz basit bir şey yok.

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

Yani evet, size söz gibi bazı metin eklemek dynamicly için kullanabilir:

Ama TextBox denetimi bir appendText() yöntemini var.

+0

Cool, Gizli olan dokümanlar ve devralınan üyeleri okuyordum. AppendText() TextBoxBase'den geldiğinden beri görmedim. – bitbonk

+0

Bu iyi çalışıyor ve hızlı: Yaklaşık bir saniye içinde bir TextBox'a 10,000 yeni satır ekleyebilirim. Tüm sanallaştırılmış olarak, kaydırma çok hızlıdır. – Contango

1
WPF RichTextBox Bu rotaya giderseniz kesinlikle FlowDocument bilgilerini okumak isteyeceksiniz.
+0

Bu temelin kutudan çıkarılmadığı bir şeye şaşırdım. Metni bir richtextbox'a nasıl bağlayacağınız hiç de sezgisel değildir. – BraveNewMath

0

Sen FlowDocument kullanabilirsiniz, ancak bu Belge özelliğine bağlamak için kutunun dışında çalışmıyor MVVM'de bir FlowDocument.

Başka bir çözüm FlowDocumentScrollViewer kullanım ve Belgesi özelliği bağlanan edilir.

(. Veya hatta bir FlowDocumentReader kullanabilir ve FlowDocumentScrollViewer benzer olan Belge özelliği yapışabilir Bu size farklı bir UI verir.)

Görünüm:

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

ViewModel:

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)); 
     } 
    } 

, ayrıca ekstra performans ipuçları için bu konuya bakın: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-text#flowdocument-textblock-and-label-controls

İlgili konular