【问题标题】:WPF: Calculating the size of a Grid ColumnWPF:计算网格列的大小
【发布时间】:2018-04-12 08:29:42
【问题描述】:

我有一个包含三列的网格。

<Grid Background="AliceBlue">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="8*" />
        <ColumnDefinition Width="5" />
        <ColumnDefinition Width="2*" Name="ManualControlsSplit" />
    </Grid.ColumnDefinitions>

第一列包含一个表格和一个图表。

第二列包含一个 GridSplitter。

第三列包含一个 StackPanel,其中包含许多 TextBlocks、Buttons 和 Grids,其中包含 TextBlocks 和 Buttons。文本大小是动态的,并且取决于翻译资源。

我需要计算第三列的内容理想情况下希望能够被绘制到的最小宽度,以便内容不会被剪裁。

我对 WPF 的了解仅限于我可以通过谷歌搜索的内容,因此我们将不胜感激。

【问题讨论】:

  • 我知道我可以将控件设置为自动调整为我希望使用以下计算的宽度:“parentColumn.Width = GridLength.Auto;”。然而这不是我想要的。
  • 我不明白。你不能将第三列设置为 Width = "Auto" 吗?
  • 我不想改变我想计算理想宽度的宽度,因为我需要在其他一些逻辑中使用该值。
  • 你无法计算(据我所知)甚至没有渲染的东西的宽度,除非你给第三列内的每个控件一个固定的宽度。最好的办法是为 Grid.Loaded 添加一个事件处理程序,然后检查实际宽度。同样,如果您将第三列设置为 Auto,您将获得所需的最小宽度
  • 进一步谷歌搜索提示测量,请参阅msdn.microsoft.com/en-us/library/…,但完全不清楚如何使用它。

标签: wpf wpf-controls


【解决方案1】:

使用 WPF 中的布局,您可以允许 Grid.Columns 中的一个(如果不是更多)为 &lt;ColumnDefinition Width="Auto"/&gt;。这实质上是告诉 WPF 允许包含的控件需要的空间。 Auto 的使用也是级联的,所以在你提到的StackPanel 中,你也可以控制宽度Auto,同样使用它包含的项目;如果堆栈面板仅包含一个TextBlock(通过某个模板或其他方式),那么您还可以将此宽度设置为Auto,并根据包含的文本自行设置宽度。

<Grid Background="AliceBlue">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="5"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    ...
    <StackPanel Grid.Column=2
                Width="Auto">  
        <TextBlock Width="Auto" 
                   Text="This is TextBlock"/> 
        ...
    </StackPanel>   
...
</Grid>

在这种情况下,TextBlockText 设置了 StackPanel 的宽度,而后者又设置了第三个网格列的宽度。

我希望这会有所帮助。

【讨论】:

  • 我实际上需要绘制项目的计算宽度。正如我所说,第二列是 GridSplitter。我可以查询每列的宽度。但是我需要知道第三列内容的“理想”绘制大小是多少。我对自动调整大小以适应内容不感兴趣。我实际上想知道计算出的自动尺寸是多少,而不是绘图。
  • WPF 将使用 Auto 并采用共享大小范围为您处理“理想绘图大小”。它将自动调整为最大的文本块。我不明白为什么这不是你的解决方案......
  • 是的,我知道如果我将宽度设置为自动,WPF 将为我处理理想的尺寸计算,并且我知道它会为我绘制内容。但这不是我问的。我想知道理想的尺寸是多少,因为我需要它来做其他事情。我不希望 WPF 执行绘图和自动调整大小。
【解决方案2】:

我的 WPF XAML 设置如下(为了简单起见,删除了一些位):

<UserControl ....>
  <Grid Background="AliceBlue" Name="TopGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="12*" Name="Graph" />
        <ColumnDefinition Width="5" Name="GridSplitter" />
        <ColumnDefinition Width="2*" Name="ManualControlsSplit" />
    </Grid.ColumnDefinitions>

    <Grid Grid.Column="0" Background="AliceBlue"
          HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <!-- A Graph and simple controls -->
    </Grid>

    <!--  GRID SPLITTER  -->
    <GridSplitter Grid.Column="1" Width="5"
          HorizontalAlignment="Stretch" Name="Splitter" />
    <Label Grid.Column="1" Content="⁞" Foreground="White" 
          Background="DarkGray"
          VerticalAlignment="Center" FontSize="26" FontWeight="Bold" 
          IsHitTestVisible="False"/>
    <!-- end GRID SPLITTER -->

    <StackPanel Grid.Column="2" Grid.Row="0" Margin="5"
          Name="TemperatureControls">
    <!-- Load of Controls -->
    </StackPanel>
  </Grid>
</UserControl>

要计算所需的宽度,我使用以下代码:

// get my UserControl object
var manualControlView = userControl as HeatingController.Views.ManualControlView;

// Query the current width of THIRD column
double actualWidth = manualControlView.ManualControlsSplit.ActualWidth;

// Set up a BIG size (this has to be bigger size than the contents of the
// THIRD column would ever need)
Size size = new Size(400, manualControlView.TopGrid.ActualHeight);

// Ask WPF layout to calculate the Desired size.
manualControlView.TemperatureControls.Measure(size);

double width = manualControlView.TemperatureControls.DesiredSize.Width;
if (actualWidth <= width)
{
   // Too small - do something
}
else
{
   // big enough - do something else.
}

变量“宽度”现在包含我要计算的值。

【讨论】:

    猜你喜欢
    • 2013-07-18
    • 2023-03-23
    • 2012-07-03
    • 2017-02-26
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    相关资源
    最近更新 更多