2009-04-30 59 views
6

Điều gì sẽ là một cách tiếp cận tốt để hiển thị và chỉnh sửa số lượng lớn các văn bản chưa định dạng (giống như notepade không) bằng cách sử dụng WPF? Việc tải một chuỗi lớn vào một Hộp văn bản khiến giao diện người dùng không phản hồi. Hiệu suất tổng thể gần như không thể so sánh được với TextBox Controls của Microsoft UI Framework trước đó.Làm cách nào để xử lý/chỉnh sửa số lượng lớn văn bản trong WPF?

Tôi có những tùy chọn nào để giải quyết vấn đề này. Tôi không muốn chặn chuỗi giao diện người dùng trong khi điều khiển văn bản tải văn bản. Ngoài ra tôi có thể cần một số loại "ảo hóa" bởi vì nó có thể không phải là một ý tưởng tốt để tải toàn bộ văn bản vào kiểm soát (tôi đoán rằng 20MB văn bản sẽ tạo ra rất nhiều glyphs ngay cả khi họ không nhìn thấy được). Dường như TextBox thậm chí không có một phương thức AppenText() nữa nên tôi thậm chí không có cách nào để kiểm soát việc tải văn bản không đồng bộ.

Đây không phải là vấn đề thường gặp phải không? Có vẻ như WPF không cung cấp bất cứ điều gì cho điều này ra khỏi hộp. Tại sao cái này rất?

+0

Tôi đã chơi với nó chỉ một chút. Vấn đề dường như có liên quan đến việc tính toán vùng cuộn. Nếu bạn tắt thanh cuộn, loại sự cố sẽ biến mất - trừ khi bạn nhấn ctrl + end (và sau đó nó phải tính đáy hoặc cái gì đó) mẫu nội dung cho hộp văn bản hte là một scrollviewer. Có lẽ vấn đề có liên quan nhiều hơn đến việc tối ưu hóa trình cuộn scrollviewer. Không phải là câu trả lời, nhưng có thể là một đầu mối? – JMarsch

Trả lời

1

AvalonEdit, trình soạn thảo văn bản trong SharpDevelop, được viết hoàn toàn từ đầu trong WPF và được tối ưu hóa cho số lượng lớn văn bản. Nó không hỗ trợ văn bản phong phú (mặc dù nó hỗ trợ làm nổi bật cú pháp và các tính năng thú vị khác như gấp). Tôi nghĩ rằng điều này có thể phù hợp với hóa đơn của bạn một cách hoàn hảo.

Dưới đây là một bài viết vào trình soạn thảo văn bản bởi nhà phát triển:

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

+1

Tôi đã quá thỏa thuận kết luận rằng việc viết kiểm soát văn bản của riêng bạn có lẽ là giải pháp tốt nhất. Đó là một chút buồn, mặc dù. – bitbonk

+3

-1. Tôi đã sử dụng AvalonEdit với các tệp 4MB hoặc lớn hơn với kết quả khủng khiếp. Vô cùng lỗi và làm hỏng ứng dụng của tôi như một kẻ đánh bom điên. – code4life

+1

Chỉ cần tạo một dự án VS WPF C# mới, thêm NuGet AvalonEdit.Sample package, thay đổi StartupUri, run and voila !, ứng dụng AvalonEdit chạy tốt. Đã mở một tệp văn bản 4MB với 8k dòng trong ít hơn một giây, trong khi TextBlock mất 22 giây. Chắc chắn có thể là một sự thay thế cho TextBlock. –

1

Bạn chỉ có thể sử dụng hộp văn bản có kiểu mang đến cho người dùng nhiều không gian hơn để xem văn bản. Có lẽ có nhiều điều khiển nâng cao hơn từ Telerik và những người khác nhưng nếu bạn không yêu cầu các tùy chọn chỉnh sửa đủ.

+0

Vấn đề chính ở đây là sự thuận lợi và khả năng sử dụng. Tôi không muốn chặn chuỗi giao diện người dùng trong khi điều khiển văn bản tải văn bản cũng có thể tôi cần một số loại "ảo hóa" vì không thể tải toàn bộ văn bản vào điều khiển (20MB văn bản sẽ tạo nhiều của glyphs). – bitbonk

+0

Trong trường hợp đó tôi sẽ đi với sự kiểm soát của bên thứ ba. Bạn có thể loại bỏ các tính năng định dạng bổ sung và giữ cho nó đơn giản như Notepad. Kiểm soát của bên thứ ba sẽ có thể xử lý tốt hơn lượng văn bản bạn đang nói đến. Bạn cũng có thể tải văn bản trên một chuỗi khác và liên kết nó với điều khiển sau khi nó được tải. – Lukasz

-1

Làm thế nào để thử một cái gì đó như thế này:

Giữ toàn bộ chuỗi trong bộ nhớ nhưng chỉ hiển thị một 'lát' của nó trong hộp văn bản. Kích thước của chuỗi được cắt lát đó sẽ được tính toán động tùy thuộc vào kích thước của hộp văn bản, kích thước phông chữ, v.v.

Tất nhiên điều này liên quan đến rất nhiều mã hiển thị, đồng bộ hóa, v.v ... đi.

1

Bạn luôn có thể trộn và kết hợp các công nghệ: bạn có thể thả một hộp văn bản WinForms lên cha mẹ WPF. Bạn mất những thứ như kiểu dáng, độ mờ đục, hoạt ảnh, biến đổi, v.v., nhưng nếu tất cả những vấn đề đó là chỉnh sửa văn bản, thì WinForms TextBox làm điều đó tốt.

+0

Điều này thật đáng buồn, nhưng có lẽ là lựa chọn tốt nhất. – bitbonk

3

Tôi không chắc liệu điều này có hữu ích hay không, nhưng bạn đã thử sử dụng FlowDocumentPageViewerFlowDocumentReader?

Nó cũng có chú thích rất tốt hỗ trợ và có vẻ lý tưởng để tải tài liệu ở định dạng văn bản.

2

Vấn đề là TextBox là một phần tử vùng chứa duy nhất. Danh sách điều khiển, chẳng hạn như ListBox ảo hóa rất tốt vì tái chế container. Có thực sự không phải là bất cứ điều gì đơn giản mà bạn có thể làm để tăng tốc độ TextBox.

Nhưng các TextBox kiểm soát không có một phương pháp AppendText():

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

Vì vậy, có, bạn có thể sử dụng để dynamicly thêm một số văn bản giống như bạn đề cập.

+0

Thật tuyệt, tôi đã đọc tài liệu và các thành viên được thừa kế ở nơi ẩn. Kể từ AppendText() đến từ TextBoxBase tôi đã không nhìn thấy nó. – bitbonk

+0

Điều này hoạt động tốt và nhanh chóng: tôi có thể thêm 10.000 hàng mới vào một TextBox trong khoảng một giây. Như tất cả của nó ảo hóa, di chuyển rất nhanh. – Contango

1

Bạn đã thử WPF RichTextBox chưa? Bạn chắc chắn sẽ muốn đọc thông tin về FlowDocument nếu bạn đi tuyến đường này.

+0

Tôi ngạc nhiên một cái gì đó cơ bản này không được xử lý ra khỏi hộp. Nó không trực quan ở tất cả cách liên kết văn bản với richtextbox. – BraveNewMath

0

Bạn có thể sử dụng FlowDocument, nhưng điều này không làm việc ra khỏi hộp để ràng buộc vào Document bất động sản của FlowDocument trong MVVM.

Một giải pháp khác đang sử dụng FlowDocumentScrollViewer và liên kết với thuộc tính tài liệu của nó.

(. Hoặc thậm chí bạn có thể sử dụng một FlowDocumentReader và ràng buộc Document tài sản của mình, tương tự như FlowDocumentScrollViewer này cung cấp cho bạn một giao diện người dùng khác nhau.)

The View:

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

cũng thấy điều này cho các mẹo hiệu suất bổ sung: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-text#flowdocument-textblock-and-label-controls

Các vấn đề liên quan