2009-06-25 16 views
31

निम्न टेक्स्टब्लॉक wraps और trims अपेक्षित के रूप में। Elipsis "..." प्रदर्शित होता है जब पाठ छंटनी होती है।मैं कैसे निर्धारित कर सकता हूं कि मेरा टेक्स्टब्लॉक टेक्स्ट छंटनी जा रहा है या नहीं?

<TextBlock 
    MaxWidth="60" 
    MaxHeight="60" 
    Text="This is some long text which I would like to wrap." 
    TextWrapping="Wrap" 
    TextTrimming="CharacterEllipsis" /> 

मैं पूरा टेक्स्ट के साथ पाठ के ऊपर एक टूलटिप प्रदर्शित करना चाहते हैं, लेकिन केवल तभी पाठ छंटनी की है। मुझे यकीन नहीं है कि कैसे "..." दिखाया जा रहा है या नहीं।

मैं कैसे निर्धारित करूं कि पाठ को छंटनी की जा रही है या नहीं?

+4

पूरी तरह से कहा गया है प्रश्न - अच्छा एक। :) –

उत्तर

9

मैंने हाल ही में बहुत सारे WPF नहीं किए हैं, इसलिए मुझे यकीन नहीं है कि यह वही है जो आप खोज रहे हैं, लेकिन इस आलेख को देखें: Customizing “lookful” WPF controls – Take 2। यह थोड़ा जटिल है, लेकिन ऐसा लगता है कि आप उसी प्रश्न को संबोधित करते हैं जो आप पूछ रहे हैं। अद्यतन: वेबसाइट चली गई है, लेकिन आप archive में आलेख पा सकते हैं।

+0

उपरोक्त आलेख में वर्णित एल्गोरिदम ठीक वही है जो मैं ढूंढ रहा था - धन्यवाद! –

+2

लिंक मर चुका है :( – l33t

+2

@ l33t मुझे लिंक की भी आवश्यकता है, [यहां पृष्ठ की एक प्रति है] (http://web.archive.org/web/20130316081653/http://tranxcoder.wordpress.com/ 2008/10/12/कस्टमाइज़िंग-लुकफुल-डब्ल्यूपीएफ-कंट्रोल-ले-2 /) वेबैक मशीन द्वारा कैश किया गया। –

18

क्योंकि Alek के उत्तर में लिंक डाउनबैक मशीन से cached copy of the link मिला है। आप आलेख में जुड़े कोड को डाउनलोड नहीं कर सकते हैं, इसलिए यहां कोड का एक पूर्व-संयोजन संस्करण है। इसे काम करने की कोशिश करते समय एक या दो मुद्दों में भाग गया था, इसलिए यह कोड लेख में उदाहरणों में कोड के बाद थोड़ा अलग है।

using System; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 

namespace TextBlockService 
{ 
    //Based on the project from http://web.archive.org/web/20130316081653/http://tranxcoder.wordpress.com/2008/10/12/customizing-lookful-wpf-controls-take-2/ 
    public static class TextBlockService 
    { 
     static TextBlockService() 
     { 
      // Register for the SizeChanged event on all TextBlocks, even if the event was handled. 
      EventManager.RegisterClassHandler(
       typeof(TextBlock), 
       FrameworkElement.SizeChangedEvent, 
       new SizeChangedEventHandler(OnTextBlockSizeChanged), 
       true); 
     } 


     private static readonly DependencyPropertyKey IsTextTrimmedKey = DependencyProperty.RegisterAttachedReadOnly("IsTextTrimmed", 
      typeof(bool), 
      typeof(TextBlockService), 
      new PropertyMetadata(false)); 

     public static readonly DependencyProperty IsTextTrimmedProperty = IsTextTrimmedKey.DependencyProperty; 

     [AttachedPropertyBrowsableForType(typeof(TextBlock))] 
     public static Boolean GetIsTextTrimmed(TextBlock target) 
     { 
      return (Boolean)target.GetValue(IsTextTrimmedProperty); 
     } 


     public static readonly DependencyProperty AutomaticToolTipEnabledProperty = DependencyProperty.RegisterAttached(
      "AutomaticToolTipEnabled", 
      typeof(bool), 
      typeof(TextBlockService), 
      new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); 

     [AttachedPropertyBrowsableForType(typeof(DependencyObject))] 
     public static Boolean GetAutomaticToolTipEnabled(DependencyObject element) 
     { 
      if (null == element) 
      { 
       throw new ArgumentNullException("element"); 
      } 
      return (bool)element.GetValue(AutomaticToolTipEnabledProperty); 
     } 

     public static void SetAutomaticToolTipEnabled(DependencyObject element, bool value) 
     { 
      if (null == element) 
      { 
       throw new ArgumentNullException("element"); 
      } 
      element.SetValue(AutomaticToolTipEnabledProperty, value); 
     } 

     private static void OnTextBlockSizeChanged(object sender, SizeChangedEventArgs e) 
     { 
      TriggerTextRecalculation(sender); 
     } 

     private static void TriggerTextRecalculation(object sender) 
     { 
      var textBlock = sender as TextBlock; 
      if (null == textBlock) 
      { 
       return; 
      } 

      if (TextTrimming.None == textBlock.TextTrimming) 
      { 
       textBlock.SetValue(IsTextTrimmedKey, false); 
      } 
      else 
      { 
       //If this function is called before databinding has finished the tooltip will never show. 
       //This invoke defers the calculation of the text trimming till after all current pending databinding 
       //has completed. 
       var isTextTrimmed = textBlock.Dispatcher.Invoke(() => CalculateIsTextTrimmed(textBlock), DispatcherPriority.DataBind); 
       textBlock.SetValue(IsTextTrimmedKey, isTextTrimmed); 
      } 
     } 

     private static bool CalculateIsTextTrimmed(TextBlock textBlock) 
     { 
      if (!textBlock.IsArrangeValid) 
      { 
       return GetIsTextTrimmed(textBlock); 
      } 

      Typeface typeface = new Typeface(
       textBlock.FontFamily, 
       textBlock.FontStyle, 
       textBlock.FontWeight, 
       textBlock.FontStretch); 

      // FormattedText is used to measure the whole width of the text held up by TextBlock container 
      FormattedText formattedText = new FormattedText(
       textBlock.Text, 
       System.Threading.Thread.CurrentThread.CurrentCulture, 
       textBlock.FlowDirection, 
       typeface, 
       textBlock.FontSize, 
       textBlock.Foreground); 

      formattedText.MaxTextWidth = textBlock.ActualWidth; 

      // When the maximum text width of the FormattedText instance is set to the actual 
      // width of the textBlock, if the textBlock is being trimmed to fit then the formatted 
      // text will report a larger height than the textBlock. Should work whether the 
      // textBlock is single or multi-line. 
      // The "formattedText.MinWidth > formattedText.MaxTextWidth" check detects if any 
      // single line is too long to fit within the text area, this can only happen if there is a 
      // long span of text with no spaces. 
      return (formattedText.Height > textBlock.ActualHeight || formattedText.MinWidth > formattedText.MaxTextWidth); 
     } 

    } 
} 
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:tbs="clr-namespace:TextBlockService"> 
    <!-- 
    Rather than forcing *all* TextBlocks to adopt TextBlockService styles, 
    using x:Key allows a more friendly opt-in model. 
    --> 

    <Style TargetType="TextBlock" x:Key="TextBlockService"> 
     <Style.Triggers> 
      <MultiTrigger> 
       <MultiTrigger.Conditions> 
        <Condition Property="tbs:TextBlockService.AutomaticToolTipEnabled" Value="True" /> 
        <Condition Property="tbs:TextBlockService.IsTextTrimmed" Value="True"/> 
       </MultiTrigger.Conditions> 

       <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Text}" /> 
      </MultiTrigger> 
     </Style.Triggers> 
    </Style> 
</ResourceDictionary> 
+0

इस तरह की वेबैक मशीन का उपयोग करके अच्छा अप। मैं भूल जाता हूं कि चीज वहां है। – MarqueIV

+0

यह पहले से ही 'ऑप्ट-इन' है क्योंकि आपको इसे 'AutomaticToolTipEnabled' के साथ सक्षम करना है। (कोड टिप्पणी के जवाब में * सभी * टेक्स्टब्लॉक को टेक्स्टब्लॉक सेवा शैलियों को अपनाने के लिए मजबूर करने के बजाय, एक्स: कुंजी का उपयोग करके अधिक अनुकूल ऑप्ट-इन मॉडल की अनुमति देता है। ') –

+0

@ केली एल्टन मैं हर किसी पर अनावश्यक ट्रिगर्स नहीं रखना चाहता था खिड़की में टेक्स्टब्लॉक।यदि आप पाते हैं कि यह किसी भी ओवरहेड का कारण नहीं है तो आप इसे प्रत्येक टेक्स्ट बॉक्स पर लागू कर सकते हैं। जिस ऐप को लिखा गया था वह डेटा एंट्री ऐप था जिसमें संपादन योग्य कोशिकाओं वाली तालिका थी, इसमें कुछ सौ टेक्स्ट बॉक्स शामिल थे। –

2

समाधान ऊपर मेरे लिए काम नहीं किया है, तो TextBlock एक ListBoxItem DataTemplate का हिस्सा है। मैं एक और समाधान का प्रस्ताव:

public class MyTextBlock : System.Windows.Controls.TextBlock 
{ 

    protected override void OnToolTipOpening(WinControls.ToolTipEventArgs e) 
    { 
     if (TextTrimming != TextTrimming.None) 
     { 
      e.Handled = !IsTextTrimmed(); 
     } 
    } 

    private bool IsTextTrimmed() 
    { 
     Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 
     return ActualWidth < DesiredSize.Width; 
    } 
} 

XAML:

<MyTextBlock Text="{Binding Text}" TextTrimming="CharacterEllipsis" ToolTip="{Binding Text}" /> 
+0

यह एक अच्छा साफ समाधान है। हालांकि यह मेरे लिए काम नहीं करता है: मेरा टेक्स्टब्लॉक छंटनी की जा रही है (मैं इलिप्सिस देखता हूं), लेकिन मेरी वांछित आकार। विथथ वास्तविक वाइडथ के बराबर है। – thehelix

0

bidy के जवाब पर विस्तार। यह एक टेक्स्टब्लॉक बनाएगा जो टूलटिप दिखाता है जब सभी टेक्स्ट नहीं दिखाए जाते हैं। टूलटिप को सामग्री में बदल दिया जाएगा (डिफ़ॉल्ट टूलटिप के विपरीत जो टेक्स्ट कट ऑफ के साथ एक लाइन बॉक्स रहेगा)।

using System; 
using System.Windows; 
using System.Windows.Controls; 

namespace Optimizers.App4Sales.LogViewer.Components 
{ 
    public class CustomTextBlock : TextBlock 
    { 
     protected override void OnInitialized(EventArgs e) 
     { 
      // we want a tooltip that resizes to the contents -- a textblock with TextWrapping.Wrap will do that 
      var toolTipTextBlock = new TextBlock(); 
      toolTipTextBlock.TextWrapping = TextWrapping.Wrap; 
      // bind the tooltip text to the current textblock Text binding 
      var binding = GetBindingExpression(TextProperty); 
      if (binding != null) 
      { 
       toolTipTextBlock.SetBinding(TextProperty, binding.ParentBinding); 
      } 

      var toolTipPanel = new StackPanel(); 
      toolTipPanel.Children.Add(toolTipTextBlock); 
      ToolTip = toolTipPanel; 

      base.OnInitialized(e); 
     } 

     protected override void OnToolTipOpening(ToolTipEventArgs e) 
     { 
      if (TextTrimming != TextTrimming.None) 
      { 
       e.Handled = !IsTextTrimmed(); 
      } 
     } 

     private bool IsTextTrimmed() 
     { 
      Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 
      return ActualWidth < DesiredSize.Width; 
     } 
    } 
} 

XAML उपयोग:

<Window ... 
     xmlns:components="clr-namespace:MyComponents" 
    ... > 

    <components:CustomTextBlock Text="{Binding Details}" TextTrimming="CharacterEllipsis" /> 
संबंधित मुद्दे

 संबंधित मुद्दे