Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Platforma WPF obejmuje obsługę prezentacji zawartości tekstowej za pomocą bogatych w funkcje kontrolek interfejsu użytkownika (UI). Ogólnie rzecz biorąc, renderowanie tekstu można podzielić na trzy warstwy:
Korzystanie z obiektu FormattedText.
Używanie kontrolek wysokiego poziomu, takich jak obiekty TextBlock i FlowDocument.
Ten temat zawiera zalecenia dotyczące wydajności renderowania tekstu.
Renderowanie tekstu na poziomie Glyph
Windows Presentation Foundation (WPF) zapewnia zaawansowaną obsługę tekstu, w tym znaczniki na poziomie glifów z bezpośrednim dostępem do Glyphs dla klientów, którzy chcą przechwycić i utrwalić tekst po sformatowaniu. Te funkcje zapewniają krytyczną obsługę różnych wymagań dotyczących renderowania tekstu w każdym z poniższych scenariuszy.
Ekran wyświetlania dokumentów w formacie stałym.
Scenariusze wydruku.
Extensible Application Markup Language (XAML) jako język drukarki urządzenia.
Składnik zapisywania dokumentów w systemie Microsoft XPS.
Poprzednie sterowniki drukarek, dane wyjściowe z aplikacji Win32 do stałego formatu.
Format buforu wydruku.
Reprezentacja dokumentu w formacie stałym, w tym klientów dla poprzednich wersji systemu Windows i innych urządzeń obliczeniowych.
Uwaga / Notatka
Glyphs i GlyphRun są przeznaczone dla scenariuszy prezentacji i drukowania dokumentów w formacie stałym. Platforma WPF udostępnia kilka elementów dla scenariuszy ogólnego układu i interfejsu użytkownika, takich jak Label i TextBlock. Aby uzyskać więcej informacji na temat scenariuszy układu i interfejsu użytkownika, zobacz Typografia w WPF.
W poniższych przykładach pokazano, jak zdefiniować właściwości obiektu Glyphs w języku XAML. W przykładach założono, że czcionki Arial, Courier New i Times New Roman są instalowane w folderze C:\WINDOWS\Fonts na komputerze lokalnym.
<!-- The example shows how to use a Glyphs object. -->
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<StackPanel Background="PowderBlue">
<Glyphs
FontUri = "C:\WINDOWS\Fonts\TIMES.TTF"
FontRenderingEmSize = "100"
StyleSimulations = "BoldSimulation"
UnicodeString = "Hello World!"
Fill = "Black"
OriginX = "100"
OriginY = "200"
/>
</StackPanel>
</Page>
Korzystanie z funkcji DrawGlyphRun
Jeśli masz kontrolkę niestandardową i chcesz renderować glify, użyj DrawGlyphRun metody .
WPF zapewnia również usługi niższego poziomu dla niestandardowego formatowania tekstu, wykorzystując obiekt FormattedText. Najbardziej wydajnym sposobem renderowania tekstu w programie Windows Presentation Foundation (WPF) jest generowanie zawartości tekstowej na poziomie glyph przy użyciu metod Glyphs i GlyphRun. Jednak koszt tej wydajności polega na utracie łatwego w użyciu formatowania tekstu, które są wbudowanymi funkcjami kontrolek Windows Presentation Foundation (WPF), takich jak TextBlock i FlowDocument.
Obiekt Sformatowanego Tekstu
Obiekt FormattedText umożliwia rysowanie tekstu wielowierszowego, gdzie każdy znak może być indywidualnie sformatowany. Aby uzyskać więcej informacji, zobacz Rysowanie sformatowanego tekstu.
Aby utworzyć sformatowany tekst, wywołaj konstruktor FormattedText, aby utworzyć obiekt FormattedText. Po utworzeniu początkowego sformatowanego ciągu tekstowego można zastosować zakres stylów formatowania. Jeśli aplikacja chce zaimplementować własny układ, FormattedText obiekt jest lepszym wyborem niż użycie kontrolki, takiej jak TextBlock. Aby uzyskać więcej informacji na temat obiektu FormattedText, zobacz Rysowanie sformatowanego tekstu.
Obiekt FormattedText zapewnia funkcję formatowania tekstu niskiego poziomu. Można zastosować wiele stylów formatowania do jednego lub więcej znaków. Można na przykład wywołać metody SetFontSize i SetForegroundBrush, aby zmienić formatowanie pierwszych pięciu znaków w tekście.
Poniższy przykład kodu tworzy FormattedText obiekt i renderuje go.
protected override void OnRender(DrawingContext drawingContext)
{
string testString = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor";
// Create the initial formatted text string.
FormattedText formattedText = new FormattedText(
testString,
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface("Verdana"),
32,
Brushes.Black);
// Set a maximum width and height. If the text overflows these values, an ellipsis "..." appears.
formattedText.MaxTextWidth = 300;
formattedText.MaxTextHeight = 240;
// Use a larger font size beginning at the first (zero-based) character and continuing for 5 characters.
// The font size is calculated in terms of points -- not as device-independent pixels.
formattedText.SetFontSize(36 * (96.0 / 72.0), 0, 5);
// Use a Bold font weight beginning at the 6th character and continuing for 11 characters.
formattedText.SetFontWeight(FontWeights.Bold, 6, 11);
// Use a linear gradient brush beginning at the 6th character and continuing for 11 characters.
formattedText.SetForegroundBrush(
new LinearGradientBrush(
Colors.Orange,
Colors.Teal,
90.0),
6, 11);
// Use an Italic font style beginning at the 28th character and continuing for 28 characters.
formattedText.SetFontStyle(FontStyles.Italic, 28, 28);
// Draw the formatted text string to the DrawingContext of the control.
drawingContext.DrawText(formattedText, new Point(10, 0));
}
Protected Overrides Sub OnRender(ByVal drawingContext As DrawingContext)
Dim testString As String = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor"
' Create the initial formatted text string.
Dim formattedText As New FormattedText(testString, CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, New Typeface("Verdana"), 32, Brushes.Black)
' Set a maximum width and height. If the text overflows these values, an ellipsis "..." appears.
formattedText.MaxTextWidth = 300
formattedText.MaxTextHeight = 240
' Use a larger font size beginning at the first (zero-based) character and continuing for 5 characters.
' The font size is calculated in terms of points -- not as device-independent pixels.
formattedText.SetFontSize(36 * (96.0 / 72.0), 0, 5)
' Use a Bold font weight beginning at the 6th character and continuing for 11 characters.
formattedText.SetFontWeight(FontWeights.Bold, 6, 11)
' Use a linear gradient brush beginning at the 6th character and continuing for 11 characters.
formattedText.SetForegroundBrush(New LinearGradientBrush(Colors.Orange, Colors.Teal, 90.0), 6, 11)
' Use an Italic font style beginning at the 28th character and continuing for 28 characters.
formattedText.SetFontStyle(FontStyles.Italic, 28, 28)
' Draw the formatted text string to the DrawingContext of the control.
drawingContext.DrawText(formattedText, New Point(10, 0))
End Sub
Kontrolki FlowDocument, TextBlock i Label
WPF zawiera wiele kontrolek do rysowania tekstu na ekranie. Każda kontrolka jest przeznaczona dla innego scenariusza i ma własną listę funkcji i ograniczeń.
FlowDocument ma wpływ na wydajność więcej niż TextBlock lub Label
Ogólnie rzecz biorąc, element TextBlock powinien być używany, gdy wymagana jest ograniczona obsługa tekstu, na przykład krótkie zdanie w interfejsie użytkownika. Label można użyć, gdy wymagana jest minimalna obsługa tekstu. Element FlowDocument jest kontenerem dla dokumentów z możliwością przepływu, które obsługują bogatą prezentację zawartości, a w związku z tym ma większy wpływ na wydajność niż używanie kontrolek TextBlock lub Label.
Aby uzyskać więcej informacji na temat FlowDocument, zobacz Omówienie dokumentu przepływu.
Unikaj używania funkcji TextBlock w elemecie FlowDocument
Element TextBlock pochodzi z elementu UIElement. Element Run pochodzi z TextElement elementu, który jest mniej kosztowny do użycia niż obiekt pochodny UIElement. Jeśli to możliwe, użyj Run zamiast TextBlock do wyświetlania zawartości tekstowej w FlowDocument.
Poniższy przykład znaczników ilustruje dwa sposoby ustawiania zawartości tekstowej w obiekcie FlowDocument:
<FlowDocument>
<!-- Text content within a Run (more efficient). -->
<Paragraph>
<Run>Line one</Run>
</Paragraph>
<!-- Text content within a TextBlock (less efficient). -->
<Paragraph>
<TextBlock>Line two</TextBlock>
</Paragraph>
</FlowDocument>
Unikaj używania uruchamiania do ustawiania właściwości tekstu
Ogólnie rzecz biorąc, korzystanie z Run wewnątrz obiektu TextBlock jest bardziej intensywnie obciążane niż nie używanie jawnego Run obiektu w ogóle. Jeśli używasz elementu Run w celu ustawienia właściwości tekstu, ustaw te właściwości bezpośrednio na elemencie TextBlock zamiast.
Poniższy przykład znaczników ilustruje te dwa sposoby ustalania właściwości tekstu, w tym przypadku właściwości FontWeight.
<!-- Run is used to set text properties. -->
<TextBlock>
<Run FontWeight="Bold">Hello, world</Run>
</TextBlock>
<!-- TextBlock is used to set text properties, which is more efficient. -->
<TextBlock FontWeight="Bold">
Hello, world
</TextBlock>
W poniższej tabeli przedstawiono koszt wyświetlania 1000 TextBlock obiektów z i bez jawnego Run.
| Typ TextBlock | Czas utworzenia (ms) | czas renderowania (ms) |
|---|---|---|
| Uruchamianie ustawień właściwości tekstu | 146 | 540 |
| Ustawianie właściwości tekstu w TextBlock | 43 | 453 |
Unikaj powiązania danych z właściwością Label.Content
Wyobraź sobie scenariusz, w którym masz obiekt Label, który jest aktualizowany często ze źródła String. Podczas wiązania danych właściwości Label elementu Content z obiektem źródłowym String, możesz doświadczyć słabej wydajności. Za każdym razem, gdy źródło String jest aktualizowane, stary String obiekt jest odrzucany, a nowy String jest ponownie utworzony — ponieważ String obiekt jest niezmienny, nie można go modyfikować. To z kolei powoduje, że komponent ContentPresenter obiektu Label odrzuca starą zawartość i generuje nową, aby wyświetlić nową String.
Rozwiązanie tego problemu jest proste. Jeśli Label nie jest ustawione na wartość niestandardową ContentTemplate, zastąp LabelTextBlock i powiąż jej właściwość Text z ciągiem źródłowym.
| Właściwość powiązana z danymi | Czas aktualizacji (ms) |
|---|---|
| Etykieta.Zawartość | 835 |
| TextBlock.Text | 242 |
Hiperłącze
Obiekt Hyperlink jest elementem zawartości przepływu na poziomie wbudowanym, który umożliwia hostowanie hiperłączy.
Łączenie hiperłączy w jednym obiekcie TextBlock
Użycie wielu Hyperlink elementów można zoptymalizować, grupując je razem w obrębie tego samego TextBlockelementu . Pomaga to zminimalizować liczbę obiektów tworzonych w aplikacji. Na przykład możesz wyświetlić wiele hiperlinków, takich jak:
MSN Home | Moja witryna MSN
Poniższy przykład znaczników przedstawia wiele TextBlock elementów używanych do wyświetlania hiperlinków:
<!-- Hyperlinks in separate TextBlocks. -->
<TextBlock>
<Hyperlink TextDecorations="None" NavigateUri="http://www.msn.com">MSN Home</Hyperlink>
</TextBlock>
<TextBlock Text=" | "/>
<TextBlock>
<Hyperlink TextDecorations="None" NavigateUri="http://my.msn.com">My MSN</Hyperlink>
</TextBlock>
Poniższy przykład znaczników przedstawia bardziej wydajny sposób wyświetlania hiperlinków, tym razem przy użyciu pojedynczego elementu TextBlock.
<!-- Hyperlinks combined in the same TextBlock. -->
<TextBlock>
<Hyperlink TextDecorations="None" NavigateUri="http://www.msn.com">MSN Home</Hyperlink>
<Run Text=" | " />
<Hyperlink TextDecorations="None" NavigateUri="http://my.msn.com">My MSN</Hyperlink>
</TextBlock>
Wyświetlanie podkreśleń na hiperlinkach tylko w przypadku zdarzeń MouseEnter
TextDecoration Obiekt jest ozdobą wizualną, którą można dodać do tekstu, ale może to być intensywne działanie, aby utworzyć wystąpienie. Jeśli często używasz elementów Hyperlink, rozważ wyświetlenie podkreślenia tylko podczas wyzwalania zdarzenia, takiego jak zdarzenie MouseEnter. Aby uzyskać więcej informacji, zobacz Określanie, czy hiperłącze jest podkreślone.
Na poniższej ilustracji pokazano, jak zdarzenie MouseEnter wyzwala podkreślone hiperłącze:
W poniższym przykładzie znaczników pokazano Hyperlink zdefiniowane z podkreśleniem i bez podkreślenia:
<!-- Hyperlink with default underline. -->
<Hyperlink NavigateUri="http://www.msn.com">
MSN Home
</Hyperlink>
<Run Text=" | " />
<!-- Hyperlink with no underline. -->
<Hyperlink Name="myHyperlink" TextDecorations="None"
MouseEnter="OnMouseEnter"
MouseLeave="OnMouseLeave"
NavigateUri="http://www.msn.com">
My MSN
</Hyperlink>
W poniższej tabeli przedstawiono koszt wydajności wyświetlania 1000 Hyperlink elementów z podkreśleniami i bez podkreślenia.
| hiperłącze | Czas utworzenia (ms) | czas renderowania (ms) |
|---|---|---|
| Z podkreśleniem | 289 | 1130 |
| Bez podkreślonia | 299 | 776 |
Funkcje formatowania tekstu
WPF zapewnia rozbudowane usługi formatowania tekstu, takie jak automatyczne dzielenie wyrazów. Te usługi mogą mieć wpływ na wydajność aplikacji i powinny być używane tylko w razie potrzeby.
Unikaj zbędnego stosowania myślników
Automatyczne dzielenie wyrazów znajduje miejsca podziału dla linii tekstu i umożliwia dodatkowe miejsca łamania dla wierszy w obiektach TextBlock i FlowDocument. Domyślnie funkcja automatycznego dzielenia wyrazów jest wyłączona w tych obiektach. Tę funkcję można włączyć, ustawiając właściwość IsHyphenationEnabled obiektu na true. Jednak włączenie tej funkcji powoduje, że WPF inicjuje współdziałanie modelu obiektów składników (COM), co może mieć wpływ na wydajność aplikacji. Zaleca się, aby nie używać automatycznego dzielenia wyrazów, chyba że jest to konieczne.
Ostrożnie używaj rysunków
Element Figure reprezentuje część zawartości przepływu, która może być całkowicie umieszczona na stronie zawartości. W niektórych przypadkach Figure może spowodować automatyczne ponowne sformatowanie całej strony, jeśli jej pozycja zderzy się z zawartością, która została już ułożona. Można zminimalizować możliwość niepotrzebnego ponownego formatowania, grupując elementy Figure obok siebie lub deklarując je blisko górnej części zawartości w przypadku ustalonego rozmiaru strony.
Optymalny akapit
Optymalna cecha akapitu FlowDocument obiektu określa akapity tak, aby odstępy są rozmieszczone tak równomiernie, jak to możliwe. Domyślnie optymalna funkcja akapitu jest wyłączona. Tę funkcję można włączyć, ustawiając właściwość obiektu IsOptimalParagraphEnabled na true. Włączenie tej funkcji ma jednak wpływ na wydajność aplikacji. Zaleca się, aby nie używać optymalnej funkcji akapitu, chyba że jest potrzebna.
Zobacz także
.NET Desktop feedback