当调整主窗口大小时,带有GridSplitter的网格调整不正确

3

我有一个可以调整大小的WPF窗口:

<Window x:Class="WpfTester.BadResize"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="BadResize"
        Height="300"
        Width="600"
        MinWidth="600">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" MinWidth="250" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Text="Left Panel" />

        <GridSplitter Grid.Column="1"
                      ResizeDirection="Columns"
                      Width="3"
                      HorizontalAlignment="Stretch" />

        <TextBox Grid.Column="2"
                 TextWrapping="Wrap"
                 Text="Test text test text test text test text test text test text test text test text test text text test text test text test text" />
    </Grid>
</Window>

这个窗口有一个左右两个面板的网格和它们之间的GridSplitter。我运行程序: enter image description here 然后我按照以下步骤进行:
  1. 将右边的窗口边框向右调整,以使文本框适合而不需要换行 enter image description here
  2. 将GridSpliiter移动到最左边(这一步很重要) enter image description here
  3. 开始将右边的窗口边框向左调整。只要文本适合文本框,它就可以正常调整大小,并且文本框会完美地调整大小。 enter image description here
  4. 一旦文本无法适合文本框并需要换行,文本框就停止调整大小并超出了窗口: enter image description here
请问您能帮我想办法通过GridSplitter来安排布局,使文本框不会超出窗口吗?
2个回答

1
经过多次实验,我发现只有在另一个元素(具有非零边距)用于测量列宽并将该值绑定到TextBox.Width时,Wrap才适用于GridSplitter。
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" MinWidth="250"/>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <TextBlock Grid.Column="0" Text="Left Panel" Name="lbl"/>

    <GridSplitter Grid.Column="1" Width="3" HorizontalAlignment="Stretch" />

    <Border Grid.Column="2" Name="test" Margin="0.05"/>

    <TextBox Grid.Column="2" 
            Width="{Binding ActualWidth, ElementName=test, Mode=OneWay}"
            TextWrapping="Wrap"
            Text="Test1 text2 test3 text4 test5 text6 test7 text8 test9 text0 test1 text2 test3 text4 test5 text6 test7 text8 text9 test0 text1 test2 text3 test4 text5" />
</Grid>

是的,它可以工作。但是,如果您在此网格的第二列中有8-10个文本框或文本块,那么调整大小会变得非常缓慢,因为当以这种方式组织布局时,FormatLine函数需要很长时间。只需复制并粘贴相同的10个文本框,将它们包装在某个网格中,运行应用程序,将GridSpliiter移动到最左边,然后尝试调整窗口大小。只有在将GridSpliiter移动到最左边时才会变慢。似乎是WPF中的一个错误。 - Oleg Ignatov
我刚刚尝试了一下(使用UniformGrid和20个以上的TextBoxes),但不能说它变慢了。我在UniformGrid上使用了Width="{Binding ActualWidth, ElementName=test, Mode=OneWay}" - ASh
非常感谢您的帮助。这个边框解决方案解决了我在DockPanel中使用TextBox时遇到的类似GridSplitter调整大小阻塞问题。令人惊讶的是,它确实需要一个非零的Margin(我将Margin设置为“1”取得了更好的效果)。使用较小的“0.05”设置,如果我点击并向右拖动足够远,就可以触发GridSplitter的“动画移动”。 - Mark Miller

0

你不应该为你的GridSplitter创建一个列。将它保留在与你的元素相同的列中。这样更可预测,你也知道它正在调整哪些列。

<Grid>
  <Grid.ColumnDefinitions>
     <ColumnDefinition Width="*" MinWidth="250" />
     <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>

    <TextBlock Grid.Column="0" Text="Left Panel" Margin="0,0,3,0"/>

    <GridSplitter Grid.Column="0"
                  ResizeDirection="Columns"
                  Width="3"
                  HorizontalAlignment="Right" VerticalAlignment="Stretch" />

    <TextBox Grid.Column="1"
             TextWrapping="Wrap"
             Text="Test text test text test text test text test text test text test text test text test text text test text test text test text" />
</Grid>

我猜将第一列的宽度设置为自动会更有意义,但当然你可以自己尝试并看看哪种方式更适合。


我同意它看起来更好,但工作方式与我在问题中描述的相同。 - Oleg Ignatov
你可能错过了第二步,将GridSplitter移动到最左边。 - Oleg Ignatov
嗯,我做到了.. 它仍然有效.. 但正如我在回答中提到的那样,我使用: <ColumnDefinition Width="Auto" MinWidth="250" /> - Nawed Nabi Zada
不,这并不酷。当第一列定义宽度为自动时,当您调整主窗口边框大小时,第一列不会被重新调整大小。这就是为什么我绝对需要列定义宽度为“*”。 - Oleg Ignatov
我刚刚复制了你的代码,它完全按照我在问题中描述的方式工作。 - Oleg Ignatov
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接