Dot-Net

WPF:如何使文本框動態調整大小但防止自動調整大小?

  • March 31, 2014

我知道關於 WPF 中文本框的自動調整大小有很多問題,但我找不到以下問題的解決方案。

考慮這個簡單的視窗:

<Window x:Class="TestVisualBrush.MainWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="MainWindow" Height="470" Width="608">
<ScrollViewer>
   <Grid>
       <Grid.RowDefinitions>
           <RowDefinition Height="Auto" />
           <RowDefinition Height="*" />
       </Grid.RowDefinitions>

       <TextBox>Test</TextBox>
       <TextBox MinHeight="100" Grid.Row="1" AcceptsReturn="True" >Test</TextBox>
   </Grid>
</ScrollViewer>
</Window>

這實現了我需要的這兩個約束:

  1. 此設置將使第二個文本框動態調整大小,以便它使用剩餘的視窗空間。
  2. 如果視窗變得太小而無法滿足所需的最小ScrollViewer內容大小,則ScrollViewer顯示捲動條。

但是,當您在第二個文本框中鍵入太多文本時,會ScrollViewer顯示捲動條,而不是TextBox. 我想阻止文本框將其高度增加到超出父級Grid最初給定的空間。在這種情況下我不能使用MaxHeight,因為沒有合適ActualHeight的綁定(據我所知)。

關於如何解決這個問題的任何建議(最好沒有程式碼隱藏)?

請注意,如果根 ScrollViewer 的內容對於視窗來說太大,它仍應滾動。

在 HTML 中,我想要的會轉化為:

<table height="100%">
<tr>
   <td><input type="text"></td>
</tr>
<tr height="100%"> 
   <td>
         <!-- Uses as much space as it gets, but scrolls if text inside
              gets too large. Makes outer window scroll if too small
              for min-height and other controls in table. -->
     <textarea style="height:100%;min-height:100px"></textarea>
   </td>
 </tr>
</table>

可滾動擴展控制項問題。

Scrollable-expandable-controls :是可以隨著內容的增長而拉伸的控制項,並且在其大小受到限制時會顯示捲動條。

當它們位於另一個可滾動控制項內時會出現問題。Child scrollable-expandable-controls 將繼續擴展,並將依靠外部可滾動控制項的捲動條。

如果你給它一個最大寬度或高度問題將得到解決,但你需要知道前面的尺寸,如果你想要一個適用於所有不同螢幕尺寸的動態應用程序,你沒有這個特權。

為了實現所需的行為,我們需要一個面板來允許其子級(可滾動擴展控制項)增長,要求他們提供所需的最小尺寸,然後在不顯示捲動條的情況下為他們提供父級提供的最大尺寸,目前有沒有這樣的面板。

這是我為提供此功能而開發的一個:

   class LimitChild : System.Windows.Controls.Panel
   {
       public LimitChild()
       {
       }

       protected override Size MeasureOverride(System.Windows.Size availableSize)
       {
           System.Diagnostics.Debug.Assert(InternalChildren.Count == 1);
           System.Windows.UIElement child = InternalChildren[0];

           Size panelDesiredSize = new Size();
           // panelDesiredSize.Width = availableSize.Width;
           panelDesiredSize.Width = (double)child.GetValue(FrameworkElement.MinWidthProperty);
           panelDesiredSize.Height = (double)child.GetValue(FrameworkElement.MinHeightProperty);

           child.Measure(panelDesiredSize);

           // IMPORTANT: do not allow PositiveInfinity to be returned, that will raise an exception in the caller! 
           // PositiveInfinity might be an availableSize input; this means that the parent does not care about sizing 
           return panelDesiredSize;
       }

       protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
       {
           System.Windows.UIElement child = InternalChildren[0];

           child.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
           if (finalSize.Width > child.RenderSize.Width)
               finalSize.Width = child.RenderSize.Width;
           if (finalSize.Height > child.RenderSize.Height)
               finalSize.Height = child.RenderSize.Height;

           return finalSize; // Returns the final Arranged size
       }
   }

然後在您的 xaml 中將您的可滾動擴展控制項封裝在其中。

       <l:LimitChild
           Grid.Row="1">
           <TextBox
               VerticalScrollBarVisibility="Auto"
               HorizontalScrollBarVisibility="Auto"
               MinHeight="200"
               AcceptsReturn="True">Test</TextBox>
       </l:LimitChild>

引用自:https://stackoverflow.com/questions/21255551