首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Powershell中的WPF网格的高度被裁剪

Powershell中的WPF网格的高度被裁剪
EN

Stack Overflow用户
提问于 2020-01-30 15:33:56
回答 1查看 222关注 0票数 2

我想用Powershell在背景图像上画一些信息。我使用WPF表单来编写这些信息,以便更好地格式化/样式化。问题是,当我必须弄乱信息的时候,DataGrid的高度会被削减,这是我不明白的。我尝试使用MaxHeight和其他不同的属性,但无法修复它。

代码语言:javascript
复制
Add-Type -AssemblyName PresentationFramework, System.Drawing

[void][System.Reflection.Assembly]::LoadWithPartialName('PresentationFramework') 
[xml]$xaml = @' 
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1" SizeToContent="WidthAndHeight"
        Name="window" Height="Auto" Width="Auto" Background="Blue" WindowStyle="ToolWindow">
    <Window.Resources>
        <Style TargetType="Grid">
            <Setter Property="ShowGridLines" Value="True"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Width" Value="Auto"/>
            <Setter Property="Height" Value="Auto"/>
        </Style>
        <Style TargetType="TableCell">
            <Setter Property="LineHeight" Value="Auto"/>
            <Setter Property="BorderThickness" Value="1"/>
        </Style>
        <Style TargetType="RowDefinition" >
            <Setter Property="Height" Value="Auto"/>
        </Style>
        <Style TargetType="TableColumn">
            <Setter Property="Width" Value="Auto"/>
        </Style>
        <Style TargetType="TextBlock" >
            <Setter Property="FontFamily" Value="Consolas" />
            <Setter Property="FontSize" Value="20" />
            <Setter Property="Foreground" Value="White" />
            <Setter Property="Margin" Value="0" />
            <Setter Property="Padding" Value="0" />
        </Style>
        <Style TargetType="DataGrid">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="GridLinesVisibility" Value="All"/>
            <Setter Property="HeadersVisibility"  Value="None"/>
        </Style>
        <Style TargetType="DataGridRow">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Height" Value="Auto"/>
        </Style>
        <Style TargetType="DataGridCell">
            <Setter Property="Height" Value="Auto"/>
            <Setter Property="Foreground" Value="White" />
            <Setter Property="FocusVisualStyle" Value="{x:Null}" />
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="FontFamily" Value="Consolas" />
            <Setter Property="FontSize" Value="20" />
        </Style>
    </Window.Resources>
    <Grid Name="Grid1" >
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,0,20" FontSize="30"><TextBlock FontSize="30" Foreground="#FFCBCBCB">This</TextBlock> is my Header!</TextBlock>
        <DataGrid Grid.Row="1" Grid.Column="0" Name="DG1" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="Auto" CanUserResize="False" CanUserReorder="False" />
                <DataGridTextColumn Header="Spacer" Binding="{Binding Spacer}" Width="50" CanUserResize="False" CanUserReorder="False" />
                <DataGridTextColumn Header="Value" Binding="{Binding Value}" Width="Auto" CanUserResize="False" CanUserReorder="False" />
            </DataGrid.Columns>
        </DataGrid>
        <TextBlock Grid.Row="2" Grid.Column="0" Padding="0,50,0,0">This is my Footer</TextBlock>
    </Grid>
</Window>
'@

# Read XAML 
$reader=(New-Object System.Xml.XmlNodeReader $xaml)

try{
    $WpfApp1=[Windows.Markup.XamlReader]::Load( $reader )
    }
catch{
    Write-Error "Unable to parse XML, with error: $($Error[0])`n Ensure that there are NO SelectionChanged or TextChanged properties (PowerShell cannot process them)"
    throw
}

# Store Form Objects In PowerShell 
$xaml.SelectNodes("//*[@Name]") | %{"trying item $($_.Name)";
    try {Set-Variable -Name "WPF_$($_.Name)" -Value $WpfApp1.FindName($_.Name) -ErrorAction Stop}
    catch{throw}
}

# Fülle Grid
for ($i=1; $i -le 60; $i++) {
    $WPF_DG1.AddChild([pscustomobject]@{Name='Test';Value=$i})   
}

$WPF_window.AllowsTransparency = $True
$WPF_window.Opacity = 0
$WPF_window.ShowInTaskbar = $False
$WPF_window.ShowActivated = $False
$WPF_window.WindowStyle = 'None'

$WpfApp1.Add_ContentRendered({
    $WpfApp1.Close()
})
$WpfApp1.ShowDialog() | out-null

[int]$infoHeight = $WPF_Grid1.ActualHeight
[int]$infoWidth = $WPF_Grid1.ActualWidth

[string]::Format("WPF_Grid1 Größe: {0}x{1}", $infoWidth, $infoHeight) | Write-Host

# Speichere WPF-Grid in Bitmap
$rBmp = New-Object Windows.Media.Imaging.RenderTargetBitmap($infoWidth, $infoHeight, 96, 96, ([Windows.Media.PixelFormats]::Pbgra32))
$rBmp.Render($WPF_Grid1)

# Konvertiere Bitmap 
$ms = New-Object System.IO.MemoryStream
$enc = New-Object System.Windows.Media.Imaging.BmpBitmapEncoder
$enc.Frames.Add([Windows.Media.Imaging.BitmapFrame]::Create($rBmp))
$enc.Save($ms)
$infoImg = [System.Drawing.Image]::FromStream($ms)
$infoImg.MakeTransparent()

[string]::Format("infoImg Größe: {0}x{1}", $infoImg.width, $infoImg.height) | Write-Host

# Lese Quell-Bild
$srcImg = [System.Drawing.Image]::FromFile($Env:WinDir + "\Web\Screen\img100.jpg")
[string]::Format("srcImg Größe: {0}x{1}", $srcImg.width, $srcImg.height) | Write-Host

# Erstelle ein Bitmap in das gezeichnet wird
$dstBmp = New-Object System.Drawing.Bitmap(([int]($srcImg.width)),([int]($srcImg.height)))

# Erstelle Graphics Objekt
$gUnit = [Drawing.GraphicsUnit]::Pixel
$gImg = [System.Drawing.Graphics]::FromImage($dstBmp)

$gImg.CompositingQuality = [System.Drawing.Drawing2D.CompositingQuality]::HighQuality
$gImg.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias
$gImg.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$gImg.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality

# Zeichne das Quell-Bild in unser gImg
$srcRect = New-Object Drawing.Rectangle(0, 0, $srcImg.Width, $srcImg.Height)
$gImg.DrawImage($srcImg, $srcRect, 0, 0, $srcImg.Width, $srcImg.Height, $gUnit)

# get scale ratio
$xpos = 150
$ypos = 150
$ratio = 0.1
while($($infoImg.Height*$ratio) -le $(($srcImg.Height-$ypos)*0.75))
{
    $ratio += 0.1
    #[string]::Format("if ({0} -le {1})", $($infoImg.Height*$ratio), $($srcImg.Height*0.75)) | Write-Host
}
[string]::Format("infoRect: X={0} Y={1} RATIO={2}", $xpos, $ypos, $ratio) | Write-Host

# Zeichne das Info-Bild in unser gImg
$infoRect = New-Object Drawing.Rectangle($xpos, $ypos, $($infoImg.Width*$ratio), $($infoImg.Height*$ratio))
$gImg.DrawImage($infoImg, $infoRect, 0, 0, $infoImg.Width, $infoImg.Height, $gUnit)

# Aufräumen
Remove-Item –Path "$($Env:Temp)\Test-*.jpg" -Force

# Neue Ausgabedatei erstellen
$dstFile = "$($Env:Temp)\Test-$(get-date -Format yyyy-MM-dd-HH-mm).jpg"
$dstBmp.save($dstFile, [System.Drawing.Imaging.ImageFormat]::Jpeg)

我添加了一个完整的工作测试代码(在win 10上-因为背景图像,你也可以更改为其他图像),它显示了问题。

检查生成的Test-*.jpg in %Temp% -我们应该看到网格的页脚。当我们将for循环更改为max 30时,整个过程都在运行...但有时我需要显示更多的信息。

希望有人能指出是什么导致了这个问题。在网上找不到相同的东西,并为此工作了几个小时……

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-03 04:14:01

在WPF中,当呈现应用程序时,实际高度被设置为监视器边界的最大值。这很有意义,因为在正常情况下,您不希望窗口比显示器大。

你为你的窗口拍摄的快照只考虑了渲染部分,这在你的例子中遗漏了一些元素。

为了避免这个问题,你想让窗口变得尽可能的大。因为您不知道窗口的高度,所以这里可以做的是设置一个任意的MinHeight值,以确保您的窗口包含所有内容。

因为它不会显示在屏幕上,并且我们不关心窗口是否越界,所以我们在这里使用3000

在那里,我们将使用Add-ContentRendered脚本块并计算网格的实际高度(页眉+数据网格+页脚)。

然后,我们将窗口的MinHeightHeight属性重置为该大小,以便快照不包含空白空间。

以下是代码中受影响的部分以及修改后的外观

代码语言:javascript
复制
# Arbitrary value to make sure all of our content will be captured
$WPF_window.MinHeight = 3000

$WpfApp1.Add_ContentRendered( {
        $MinHeight = ($WPF_Grid1.RowDefinitions.ActualHeight | Measure-Object -Sum) |
        Select -ExpandProperty Sum
        $WPF_window.MinHeight = $MinHeight
        $WPF_window.Height = $MinHeight
        $WpfApp1.Close()
    })
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59981067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档