2011-01-21 5 views
5

में फिट बैठता है, मुझे एक WPF कैनवास पर शब्दों को इस तरह से प्रदर्शित करने की आवश्यकता है कि वे पूर्व-निर्धारित बॉक्स में पूरी तरह से फिट हों।डब्ल्यूपीएफ में पाठ प्रस्तुत करना ताकि यह पूरी तरह से दिए गए आयताकार

एक बॉक्स में आम तौर पर एक अक्षर से कुछ शब्दों में पाठ की एक पंक्ति होती है।

बॉक्स के अंदर का पाठ जितना संभव हो उतना बड़ा होना चाहिए, यानी: बॉक्स की सभी सीमाओं को छूना (शायद यह छोड़कर कि यह असामान्य बॉक्स witdh/ऊंचाई अनुपात के कारण बहुत अधिक टेक्स्ट विकृति का कारण बनता है)।

मुझे टेक्स्ट सामग्री के आधार पर उपयुक्त फ़ॉन्ट ऊंचाई, स्केलिंग और ऑफ़सेट की गणना करने का एक अच्छा तरीका नहीं मिला।

पहला समाधान जहां मूल पाठ चौड़ाई/ऊंचाई अनुपात बदला नहीं जा सकता है, वह पहले से ही बहुत अच्छा होगा!

मैं टेक्स्टब्लॉक तत्वों का उपयोग करना चाहता हूं, लेकिन जो कुछ भी काम करता है वह ठीक होना चाहिए।

उत्तर

5

रॉबरी लेवी के जवाब के अनुसार, आप इसे प्राप्त करने के लिए Viewbox का उपयोग कर सकते हैं। पाठ स्वयं ही नहीं फैलाएगा, इसलिए आपके टेक्स्ट के आधार पर आपके पास शून्य या अधिक पक्षों पर कुछ "मार्जिन" होगा (जैसा आपने देखा था)। इसके आस-पास काम करने के लिए आप एक कस्टम नियंत्रण बना सकते हैं जो Geometry को FormattedText से बनाता है और फिर इसे ऑनरेंडर में DrawGeometry के साथ खींचें। आप देखेंगे कि टेक्स्ट की गुणवत्ता बड़े FontSize के साथ कैसे सुधारती है। एक बहुत छोटी पाठ (जैसे FontSize="10") एक बड़े Viewbox में बहुत तेज नहीं लग जाएगा, ताकि आप थोड़ा

enter image description here

कुछ नमूना Xaml

<Canvas Background="Black"> 
    <Viewbox Canvas.Left="10" Canvas.Top="10" 
      Stretch="Fill" Width="200" Height="50"> 
     <Border Background="Red"> 
      <local:StretchText Text="Text" Foreground="Green" FontSize="100"/> 
     </Border> 
    </Viewbox> 
    <Viewbox Canvas.Left="230" Canvas.Top="10" 
      Stretch="Fill" Width="200" Height="50"> 
     <Border Background="Red"> 
      <local:StretchText Text="B" Foreground="Green" FontSize="500"/> 
     </Border> 
    </Viewbox> 
</Canvas> 

StretchText प्रयोग करने के लिए होगा .cs

public class StretchText : Control 
{ 
    protected override void OnRender(DrawingContext drawingContext) 
    { 
     FormattedText formattedText = new FormattedText(
      Text, 
      CultureInfo.GetCultureInfo("en-us"), 
      FlowDirection.LeftToRight, 
      new Typeface(FontFamily, FontStyle, FontWeight, FontStretches.Normal), 
      FontSize, 
      Foreground); 

     Geometry textGeometry = formattedText.BuildGeometry(new Point(0, 0)); 
     this.MinWidth = textGeometry.Bounds.Width; 
     this.MinHeight = textGeometry.Bounds.Height; 

     TranslateTransform translateTransform = new TranslateTransform(); 
     translateTransform.X = -textGeometry.Bounds.Left; 
     translateTransform.Y = -textGeometry.Bounds.Top; 
     drawingContext.PushTransform(translateTransform); 
     drawingContext.DrawGeometry(Foreground, new Pen(Foreground, 1.0), textGeometry); 
    } 

    public string Text 
    { 
     get { return (string)GetValue(TextProperty); } 
     set { SetValue(TextProperty, value); } 
    } 
    public static readonly DependencyProperty TextProperty = 
     DependencyProperty.Register("Text", 
     typeof(string), 
     typeof(StretchText), 
     new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsRender)); 
} 
+0

धन्यवाद! मैंने इसका परीक्षण किया और यह बहुत अच्छी तरह से काम करता है। इस बीच मुझे एक वैकल्पिक समाधान मिला: एक अस्थायी स्वरूपित टेक्स्ट ऑब्जेक्ट (गुणों "चौड़ाई", "विस्तार" और "ओवरहैंगएफ़टर") के माध्यम से पाठ तत्वों को मापना, फिर तदनुसार प्रत्येक तत्व को स्केल + अनुवाद ट्रान्सफॉर्म लागू करें। हालांकि, इसके दो नुकसान हैं: वास्तविक टेक्स्ट ब्लॉक ऑब्जेक्ट्स बहुत बड़े हो जाते हैं (मैसेजिंग टूलटिप्स), और प्रतिपादन उतना तेज नहीं है जितना मैं चाहूंगा। – Jem

+1

@ जेम: कोई समस्या नहीं :) हमारे समाधानों के बीच प्रतिपादन समय कैसा रहा? क्या दोनों मामलों में "धीमा" था? मैंने एक 'ग्रिड' में एक साथ 10 या तो 'स्ट्रेचटेक्स्ट' के साथ प्रयास किया और फिर 'विंडो' को तुरंत बदल दिया। मुझे बहुत अच्छी तरह से काम करना प्रतीत होता था लेकिन 'DrawGeometry' बहुत धीमी होने के लिए जाना जाता है –

+0

प्रदर्शित करने के लिए शब्दों की संख्या लगभग एक या दो हजार है, लेकिन पृष्ठ का आकार बदलना आपके समाधान के साथ पर्याप्त है। मैं कहूंगा कि यह मेरी तुलना में लगभग 3 गुना तेज है, और यह स्थिर है (कोई "लेट" नहीं)।हालांकि, पाठ की गुणवत्ता छोटे पाठ के लिए उतनी तेज नहीं है (संभवतः क्योंकि यह अब "टेक्स्ट" नहीं है, लेकिन "ज्यामिति") है, लेकिन यह काफी अच्छा है। आदर्श रूप में मैं भी बेहतर प्रदर्शन और सर्वोत्तम संभव पाठ गुणवत्ता चाहता हूं, लेकिन आपका समाधान अब के लिए सबसे अच्छा समझौता है। – Jem

4

एक Viewbox अंदर TextBlock रखो: http://msdn.microsoft.com/en-us/library/system.windows.controls.viewbox.aspx

+0

धन्यवाद , प्रयास किया। दिलचस्प है लेकिन यह वही नहीं करता जो मुझे चाहिए: यह टेक्स्ट सामग्री के बारे में पता नहीं है। उदाहरण के लिए, मेरे पास अभी भी टेक्स्ट के नीचे मार्जिन है जब तक कोई पत्र बेसलाइन (जैसे 'g', 'p', 'y' 'q') को पार नहीं करता है। मुझे "बॉडिंग बॉक्स" टेक्स्ट होने के लिए वास्तव में इनपुट बॉक्स की आवश्यकता है। – Jem

0

आप चार्ल्स पेज़ॉल्ड के लेख "Render Text on a Path with WPF" की जाँच कर सकते हैं। दुर्भाग्य से मैं वर्तमान समय में एमएसडीएन साइट के साथ कुछ गलत होने के कारण विषय के बारे में अपने जानकारियों को ताज़ा नहीं कर सकता, लेकिन उन्होंने वर्णन किया कि पथ के भीतर पाठ को कैसे स्केल करना है।