This article has been localized into Vietnamese by the community.
Control FlowDocumentScrollViewer
Trong các control FlowDocument, FlowDocumentScrollViewer là control đơn giản nhất. Nó chỉ đơn giản là một thanh cuộn để cho người dùng xem được toàn bộ nội dung của 1 nội dung dài. Vì đây là bài đầu tiên nói về FlowDocument được sử dụng trong các trường hợp khác nhau, nên chúng tôi sẽ bắt đầu với câu "Hello World!" và bên cạnh việc sử dụng control FlowDocumentScrollViewer, bài viết này cũng sẽ đề cập đến một số khái niệm chung giữa tất cả các control trong nhóm FlowDocument. Đây là ví dụ đầu tiên:
<Window x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentScrollViewerSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FlowDocumentScrollViewerSample" Height="200" Width="300">
<Grid>
<FlowDocumentScrollViewer>
<FlowDocument>
<Paragraph FontSize="36">Hello, world!</Paragraph>
<Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">The ultimate programming greeting!</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
</Grid>
</Window>
Chú ý trong ví dụ này có sử dụng 1 tag mới dùng để đánh dấu đây là văn bản là Paragraph. Ngay lúc này bạn sẽ tự hỏi là: Nếu như vậy ta có thể dùng control TextBlock được mà, có cái gì mà không được đâu. Điều này đúng, mình không phủ nhận bạn. Nhưng, nếu bạn làm như đoạn code ở trên, thì bạn thử chạy, bôi đen dòng chữ "Hello World" rồi chuột phải như hình dưới xem. Chắc chắn với bạn luôn nó sẽ được đưa vào Clipboard. Thật tuyệt vời phải không?
Thu - phóng (Zooming) và hiển thị thanh cuộn (scrollbar) để thực hiện thu - phóng
Bây giờ bạn sẽ đặt ra câu hỏi như thế này: Liệu tôi có thể giữ phím Control (Ctrl) rồi lăn chuột để thực hiện thu - phóng hay không? Câu trả lời là hoàn toàn có thể. Tuy nhiên, có nhiều người họ không quen việc này. Do đó bạn cần show ra cho họ thanh để thu - phóng. Bạn chỉ cần thêm 1 thuộc tính duy nhất mang tên IsToolBarVisible. Bạn có thể thử đoạn code ngay ở bên dưới, và kết quả có ngay ở hình bên dưới đoạn code.
<Window x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentScrollViewerZoomSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FlowDocumentScrollViewerZoomSample" Height="180" Width="300">
<Grid>
<FlowDocumentScrollViewer IsToolBarVisible="True" Zoom="80" ScrollViewer.VerticalScrollBarVisibility="Auto">
<FlowDocument>
<Paragraph FontSize="36">Hello, world!</Paragraph>
<Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">The ultimate programming greeting!</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
</Grid>
</Window>
Bây giờ người dùng có thể điều khiển mức thu phóng bằng cách sử dụng thanh trượt và các nút trên thanh công cụ ở ngay bên dưới form. Cũng lưu ý rằng ở trong ví dụ trên đã sử dụng thuộc tính Zoom. Khi bắt đầu chạy chương trình nó sẽ đặt kích cỡ theo như giá trị đặt trong thuộc tính này. (Thấp nhất là 80 và cao nhất là 200, nếu mình nói sai thì các bạn chỉnh lại giúp mình nhé).
Cũng trong đoạn code trên tác giả đã dùng thêm 1 thuộc tính nữa có tên là ScrollViewer.VerticalScrollBarVisibility. Ở đây chọn Auto, có nghĩa là chỉ khi nào nội dung quá nhiều dòng thì thanh ScrollBar mới hiển thị. Đây cũng là tùy chọn khuyên dùng.
Căn chỉnh văn bản (Text alignment)
Bạn có thể nhận thấy rằng tôi đã sử dụng thuộc tính TextAlignment trong các ví dụ trên. Đó là bởi vì theo mặc định thì rất là xấu vì nếu như văn bản có một khoảng trống quá dài (chẳng hạn như ở hình dưới) thì nó sẽ tạo ra những khoảng có dấu cách rất nhiều dẫn đến không hợp thẩm mĩ cho lắm. Bạn có thể thấy trong đoạn code dưới đây, ta có thể đặt từng thuộc tính riêng rẽ ra qua việc đặt từng thuộc tính riêng cho từng element FlowDocument.
Tuy nhiên, trong nhiều tình huống, tuy khắc phục được lỗi trên, nhưng nó có thể dẫn đến một lượng khoảng trắng quá lớn trên các dòng có dấu ngắt dòng được chèn ngay trước một từ rất dài.
Ví dụ sau sẽ cung cấp giải pháp giúp khắc phục sự cố. Bằng cách sử dụng thuộc tính IsOptimalParagraphEnabled kết hợp với thuộc tính IsHyphenationEnabled sẽ giúp bạn trình bày văn bản theo cách tốt nhất có thể.
Thuộc tính IsOptimalParagraphEnabled sẽ làm cho WPF hiểu rằng bạn có cần xét trước từ tiếp theo, làm sao để khi ngắt dòng cũng không quá dài (nói chung là hợp lí cho việc ngắt dòng), còn thuộc tính IsHyphenationEnabled cho phép tách các từ của bạn bằng dấu gạch nối, nếu điều đó làm cho văn bản trở nên đẹp hơn.
Trong ví dụ tiếp theo, tôi đã cho hiển thị cùng một văn bản hai lần - một không có các thuộc tính này và một là có. Sự khác biệt là khá rõ ràng:
<Window x:Class="WpfTutorialSamples.Rich_text_controls.FlowDocumentTextAlignmentSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FlowDocumentTextAlignmentSample" Height="400" Width="330">
<StackPanel>
<FlowDocumentScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
<FlowDocument>
<Paragraph FontStyle="Italic" FontSize="14" Foreground="Gray">
By setting the
<Bold>IsOptimalParagraphEnabled</Bold> property to true,
you will allow WPF to look ahead on the lines to come, before deciding
where to break. This will usually result in a more pleasant reading
experience. It works especially well in combination with the
<Bold>IsHyphenationEnabled</Bold> property.
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
<FlowDocumentScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
<FlowDocument IsOptimalParagraphEnabled="True" IsHyphenationEnabled="True">
<Paragraph FontStyle="Italic" FontSize="14" Foreground="Gray">
By setting the <Bold>IsOptimalParagraphEnabled</Bold> property to true,
you will allow WPF to look ahead on the lines to come, before deciding
where to break. This will usually result in a more pleasant reading
experience. It works especially well in combination with the
<Bold>IsHyphenationEnabled</Bold> property.
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
</StackPanel>
</Window>
Vì IsOptimalParagraphEnabled yêu cầu nhiều sức mạnh CPU hơn một chút khi hiển thị văn bản, đặc biệt nếu cửa sổ thường xuyên được thay đổi kích thước, nên nó không được bật theo mặc định. Đối với hầu hết các ứng dụng, điều này không thành vấn đề.
Nếu bạn có nhiều FlowDocument trong ứng dụng của mình và bạn thích hai thuộc tính này, bạn có thể bật nó trên tất cả các FlowDocument bằng cách copy đoạn code này vào file App.xaml của bạn.
<Application x:Class="WpfTutorialSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
StartupUri="Rich text controls/FlowDocumentTextAlignmentSample.xaml">
<Application.Resources>
<Style TargetType="FlowDocument">
<Setter Property="IsOptimalParagraphEnabled" Value="True" />
<Setter Property="IsHyphenationEnabled" Value="True" />
</Style>
</Application.Resources>
</Application>