WPF TextBlock में स्वचालित वर्टिकल स्क्रॉल बार?


335

मैंने TextBlockWPF में ए । मैं इसकी कई पंक्तियाँ लिखता हूँ, इसकी ऊर्ध्वाधर ऊँचाई से अधिक। मुझे उम्मीद थी कि जब ऐसा होता है तो एक वर्टिकल स्क्रॉल बार अपने आप दिखाई देगा, लेकिन ऐसा नहीं हुआ। मैंने प्रॉपर्टीज फलक में एक स्क्रॉल बार प्रॉपर्टी देखने की कोशिश की, लेकिन एक नहीं मिल पाई।

TextBlockएक बार इसकी सामग्री की ऊँचाई से अधिक हो जाने के बाद , मैं अपने आप वर्टिकल स्क्रॉल बार कैसे बना सकता हूँ ?

स्पष्टता: मैं इसे डिज़ाइनर से नहीं बल्कि सीधे XAML से लिखकर लिखूंगा।


1
इस प्रश्न को फिर से पढ़ने पर, मैं आपको TextBlockदो बार और TextBoxएक बार उल्लेख करता हूं ।
ड्रू नॉक

जवाबों:


555

इसे एक स्क्रॉल दर्शक में लपेटें:

<ScrollViewer>
    <TextBlock />
</ScrollViewer>

ध्यान दें कि यह उत्तर TextBlockमूल प्रश्न में पूछे गए एक (केवल-पाठ तत्व) पर लागू होता है ।

यदि आप TextBox(एक संपादन योग्य पाठ तत्व) में स्क्रॉल बार दिखाना चाहते हैं, तो ScrollViewerसंलग्न गुणों का उपयोग करें :

<TextBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"
         ScrollViewer.VerticalScrollBarVisibility="Auto" />

इन दो गुणों के लिए मान्य मान रहे हैं Disabled, Auto, Hiddenऔर Visible


2
मैं इसे डिजाइनर से कैसे करूँ?
बाबा योगू

16
क्षमा करें, मुझे यकीन नहीं है, मैं WPF डिजाइनर का उपयोग नहीं करता। मुझे लगता है कि अगर आप सीधे XAML जोड़ते हैं, तो डिजाइनर खुद को अपडेट करेगा।
ड्रू नॉक

5
@conqenator TextBox.ScrollToEnd ();
पेटी बी

2
@Greg, सवाल यह TextBlockनहीं है TextBox
ड्रू नॉक

7
कभी-कभी स्क्रॉलव्यूअर पर एक मैक्सहाइट को यह दिखाने के लिए मजबूर करने की आवश्यकता होती है कि क्या संलग्नक तत्व किसी भी ऊंचाई को लागू नहीं करता है।
HackerBaloo

106

अब निम्नलिखित का उपयोग कर सकते हैं:

<TextBox Name="myTextBox" 
         ScrollViewer.HorizontalScrollBarVisibility="Auto"
         ScrollViewer.VerticalScrollBarVisibility="Auto"
         ScrollViewer.CanContentScroll="True">SOME TEXT
</TextBox>

19
@jjnguy, मैंने मूल प्रश्न की व्याख्या की है, जैसा TextBlockकि TextBox(शीर्षक और उद्घाटन पंक्ति में) नहीं है, लेकिन दूसरे पैराग्राफ में उल्लेख किया गया है TextBox। स्पष्ट होने के लिए, यह उत्तर निश्चित रूप से टेक्स्ट बॉक्स के लिए सबसे अच्छा तरीका है , और मेरा सबसे अच्छा है जो मुझे टेक्स्ट ब्लॉक के लिए पता है :)
ड्रू नोक

@ आकर्षित, आह, समझ में आता है। स्पष्टीकरण के लिए धन्यवाद।
jjnguy

2
मेरे लिए भी बेहतर काम किया। पाठ बॉक्स के लिए कम से कम, जब इसके चारों ओर स्क्रॉल दृश्य का उपयोग किया जाता है, तो स्वीकृत उत्तर की तरह, पाठ बॉक्स की सीमाएँ गायब हो जाती हैं, क्योंकि संपूर्ण नियंत्रण स्क्रॉल किया जाता है, और न केवल इसकी सामग्री।
ईंधन

20

कुछ बेहतर होगा:

<Grid Width="Your-specified-value" >
    <ScrollViewer>
         <TextBlock Width="Auto" TextWrapping="Wrap" />
    </ScrollViewer>
</Grid>

इससे यह सुनिश्चित होता है कि आपके टेक्स्टब्लॉक में टेक्स्ट ओवरफ्लो नहीं करता है और टेक्स्टब्लॉक के नीचे के तत्वों को ओवरलैप कर सकता है जैसा कि ग्रिड का उपयोग न करने पर हो सकता है। मेरे साथ ऐसा तब हुआ जब मैंने अन्य समाधानों की कोशिश की, हालांकि टेक्स्टब्लॉक पहले से ही अन्य तत्वों के साथ ग्रिड में था। ध्यान रखें कि टेक्स्टब्लॉक की चौड़ाई ऑटो होनी चाहिए और आपको ग्रिड तत्व के साथ वांछित निर्दिष्ट करना चाहिए। मैंने अपने कोड में ऐसा किया है और यह खूबसूरती से काम करता है। HTH।


7
<ScrollViewer Height="239" VerticalScrollBarVisibility="Auto">
    <TextBox AcceptsReturn="True" TextWrapping="Wrap" LineHeight="10" />
</ScrollViewer>

यह XAML में स्क्रॉलिंग टेक्स्टबॉक्स का उपयोग करने और इसे पाठ क्षेत्र के रूप में उपयोग करने का तरीका है।


1
सवाल TextBlockनहीं से संबंधित है TextBox
अफजल अहमद जीशान

बहुत सही उत्तर नहीं है, लेकिन मैंने पाया कि वर्टिकलस्क्रोलबर्विबिलिटी एक उपयोगी संकेत है इसलिए +1
मलाकी

4

यह उत्तर MVVM के उपयोग से समाधान का वर्णन करता है।

यह समाधान बहुत अच्छा है यदि आप एक लॉगिंग बॉक्स को एक विंडो में जोड़ना चाहते हैं, जो कि हर बार एक नया लॉगिंग संदेश जुड़ने पर स्वचालित रूप से नीचे स्क्रॉल करता है।

एक बार इन संलग्न गुणों को जोड़ने के बाद, उन्हें कहीं भी पुन: उपयोग किया जा सकता है, इसलिए यह बहुत ही मॉड्यूलर और पुन: प्रयोज्य सॉफ़्टवेयर के लिए बनाता है।

इस XAML को जोड़ें:

<TextBox IsReadOnly="True"   
         Foreground="Gainsboro"                           
         FontSize="13" 
         ScrollViewer.HorizontalScrollBarVisibility="Auto"
         ScrollViewer.VerticalScrollBarVisibility="Auto"
         ScrollViewer.CanContentScroll="True"
         attachedBehaviors:TextBoxApppendBehaviors.AppendText="{Binding LogBoxViewModel.AttachedPropertyAppend}"                                       
         attachedBehaviors:TextBoxClearBehavior.TextBoxClear="{Binding LogBoxViewModel.AttachedPropertyClear}"                                    
         TextWrapping="Wrap">

इस संलग्न संपत्ति जोड़ें:

public static class TextBoxApppendBehaviors
{
    #region AppendText Attached Property
    public static readonly DependencyProperty AppendTextProperty =
        DependencyProperty.RegisterAttached(
            "AppendText",
            typeof (string),
            typeof (TextBoxApppendBehaviors),
            new UIPropertyMetadata(null, OnAppendTextChanged));

    public static string GetAppendText(TextBox textBox)
    {
        return (string)textBox.GetValue(AppendTextProperty);
    }

    public static void SetAppendText(
        TextBox textBox,
        string value)
    {
        textBox.SetValue(AppendTextProperty, value);
    }

    private static void OnAppendTextChanged(
        DependencyObject d,
        DependencyPropertyChangedEventArgs args)
    {
        if (args.NewValue == null)
        {
            return;
        }

        string toAppend = args.NewValue.ToString();

        if (toAppend == "")
        {
            return;
        }

        TextBox textBox = d as TextBox;
        textBox?.AppendText(toAppend);
        textBox?.ScrollToEnd();
    }
    #endregion
}

और यह संलग्न संपत्ति (बॉक्स खाली करने के लिए):

public static class TextBoxClearBehavior
{
    public static readonly DependencyProperty TextBoxClearProperty =
        DependencyProperty.RegisterAttached(
            "TextBoxClear",
            typeof(bool),
            typeof(TextBoxClearBehavior),
            new UIPropertyMetadata(false, OnTextBoxClearPropertyChanged));

    public static bool GetTextBoxClear(DependencyObject obj)
    {
        return (bool)obj.GetValue(TextBoxClearProperty);
    }

    public static void SetTextBoxClear(DependencyObject obj, bool value)
    {
        obj.SetValue(TextBoxClearProperty, value);
    }

    private static void OnTextBoxClearPropertyChanged(
        DependencyObject d,
        DependencyPropertyChangedEventArgs args)
    {
        if ((bool)args.NewValue == false)
        {
            return;
        }

        var textBox = (TextBox)d;
        textBox?.Clear();
    }
}   

फिर, यदि आप MEF जैसे एक निर्भरता इंजेक्शन ढांचे का उपयोग कर रहे हैं, तो आप लॉगिंग-विशिष्ट कोड के सभी को अपने ViewMelel में रख सकते हैं:

public interface ILogBoxViewModel
{
    void CmdAppend(string toAppend);
    void CmdClear();

    bool AttachedPropertyClear { get; set; }

    string AttachedPropertyAppend { get; set; }
}

[Export(typeof(ILogBoxViewModel))]
public class LogBoxViewModel : ILogBoxViewModel, INotifyPropertyChanged
{
    private readonly ILog _log = LogManager.GetLogger<LogBoxViewModel>();

    private bool _attachedPropertyClear;
    private string _attachedPropertyAppend;

    public void CmdAppend(string toAppend)
    {
        string toLog = $"{DateTime.Now:HH:mm:ss} - {toAppend}\n";

        // Attached properties only fire on a change. This means it will still work if we publish the same message twice.
        AttachedPropertyAppend = "";
        AttachedPropertyAppend = toLog;

        _log.Info($"Appended to log box: {toAppend}.");
    }

    public void CmdClear()
    {
        AttachedPropertyClear = false;
        AttachedPropertyClear = true;

        _log.Info($"Cleared the GUI log box.");
    }

    public bool AttachedPropertyClear
    {
        get { return _attachedPropertyClear; }
        set { _attachedPropertyClear = value; OnPropertyChanged(); }
    }

    public string AttachedPropertyAppend
    {
        get { return _attachedPropertyAppend; }
        set { _attachedPropertyAppend = value; OnPropertyChanged(); }
    }

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

यहां देखिए यह कैसे काम करता है:

  • ViewModel टेक्स्टबॉक्स को नियंत्रित करने के लिए संलग्न गुणों को टॉगल करता है।
  • जैसा कि यह "परिशिष्ट" का उपयोग कर रहा है, यह तेज़ बिजली है।
  • कोई अन्य ViewModel लॉगिंग ViewModel पर तरीकों को कॉल करके लॉगिंग संदेश उत्पन्न कर सकता है।
  • जैसे ही हम पाठ बॉक्स में बने स्क्रॉलव्यूअर का उपयोग करते हैं, हम हर बार एक नया संदेश जुड़ने के बाद इसे पाठ बॉक्स के निचले भाग तक स्क्रॉल कर सकते हैं।

4
<ScrollViewer MaxHeight="50"  
              Width="Auto" 
              HorizontalScrollBarVisibility="Disabled"
              VerticalScrollBarVisibility="Auto">
     <TextBlock Text="{Binding Path=}" 
                Style="{StaticResource TextStyle_Data}" 
                TextWrapping="Wrap" />
</ScrollViewer>

मैं स्क्रॉलहाइज़र में मैक्सहाइट डालकर इसे दूसरे तरीके से कर रहा हूँ।

पाठ की अधिक या कम पंक्तियों को दिखाने के लिए बस मैक्सहाइट को समायोजित करें। आसान।



1

मैंने इन सुझावों को एक टेक्स्टब्लॉक के लिए काम करने की कोशिश की, लेकिन इसे काम करने के लिए नहीं मिला। मैंने इसे डिजाइनर से काम करने की कोशिश भी की। (लेआउट में देखें और नीचे की ओर "V" पर क्लिक करके सूची का विस्तार करें) मैंने स्क्रॉल को विज़िबल और फिर ऑटो में सेट करने की कोशिश की , लेकिन यह अभी भी काम नहीं करेगा।

मैं अंत में छोड़ दिया और बदल TextBlockएक को TextBoxसाथ केवल पढ़ने के लिए विशेषता सेट, और यह एक आकर्षण की तरह काम किया।


0

न पता है किसी और को इस समस्या है, लेकिन अगर मेरी लपेटकर TextBlockएक में ScrollViewersomewhow मेरी यूआई में गड़बड़ - के रूप में एक सरल वैकल्पिक हल मैं पता लगा कि जगह TextBlockएक से TextBoxइस तरह

<TextBox  Name="textBlock" SelectionBrush="Transparent" Cursor="Arrow" IsReadOnly="True" Text="My Text" VerticalScrollBarVisibility="Auto">

एक स्क्रॉलबार के साथ TextBoxजैसा दिखता है और व्यवहार करता है TextBlock(और आप डिजाइनर में यह सब कर सकते हैं) बनाता है ।


0

यह उस प्रश्न का एक सरल समाधान है। वर्टिकल स्क्रॉल तभी एक्टिवेट होगा जब टेक्स्ट ओवरफ्लो होगा।

<TextBox Text="Try typing some text here " ScrollViewer.VerticalScrollBarVisibility="Auto" TextWrapping="WrapWithOverflow" />

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.