视图框干扰网格列的水平对齐

huangapple go评论75阅读模式
英文:

Viewbox interfering grid columns horizontal alignment

问题

我正在使用一个Stretch属性设置为Uniform的Viewbox,以便在用户切换屏幕分辨率和操作系统的缩放时不会扭曲内容。

在Viewbox内部,我有一个网格(Grid)。
这个网格只有一行和一些列。

<Viewbox StretchDirection="Both" 
         Stretch="Uniform"
         HorizontalAlignment="Left"
         VerticalAlignment="Stretch">
    <Grid Focusable="True" Height="Auto">
        <Grid.ColumnDefinitions>
            <!-- 动画图像 -->
            <ColumnDefinition Width="Auto" />
            <!-- 带有图标和文本的堆栈面板 -->
            <ColumnDefinition Width="Auto" />
            <!-- 垂直分隔线 -->
            <ColumnDefinition Width="Auto" />
            <!-- 按钮 -->
            <ColumnDefinition Width="Auto" />
            <!-- 空白的虚拟列,用于正确分配空间,使下一列水平右对齐 -->
            <ColumnDefinition Width="*" />
            <!-- 帮助按钮 -->
            <ColumnDefinition Width="Auto" />
            <!-- 三个点的按钮 -->
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0" Orientation="Horizontal" Visibility="{Binding Path=IsAnimatedImgVisible, Converter={StaticResource BoolToVisibility}}">
            <v:UserControlAnimatedImg x:Name="UcSpinner" VerticalAlignment="Center" HorizontalAlignment="Left"/>
            <Label SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="HighQuality" VerticalAlignment="Center" HorizontalAlignment="Left" Content="{Binding Path=StatusText}"/>
        </StackPanel>

        <StackPanel Grid.Column="1" Orientation="Horizontal">
            <Image
               Margin="10,5"
               Height="24"
               Width="24"
               MaxHeight="24"
               MaxWidth="24"
               VerticalAlignment="Center"
               HorizontalAlignment="Center"
               Stretch="None" 
               SnapsToDevicePixels="True"
               RenderOptions.BitmapScalingMode="HighQuality"
               Source="{Binding Path=Icon}"/>
            <Label 
               VerticalAlignment="Center"
               HorizontalAlignment="Left"
               Content="{Binding Path=StatusTxt}"
               SnapsToDevicePixels="True"
               RenderOptions.BitmapScalingMode="HighQuality">
            </Label>
        </StackPanel>

        <Separator Grid.Column="2" Margin="10,5,5,5" Height="26" Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}"/>

        <Button Grid.Column="3" Height="Auto" Width="150" Command="{Binding ButtonOnClick}">
            <StackPanel Orientation="Horizontal">
                <Image 
                   Height="24"
                   Width="25"
                   MaxHeight="24"
                   MaxWidth="25"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"
                   Stretch="None" 
                   SnapsToDevicePixels="True"
                   RenderOptions.BitmapScalingMode="HighQuality"
                   Source="{Binding ImageIcon}"/>
                <TextBlock
                       Margin="10,2,5,2"
                       VerticalAlignment="Center"
                       HorizontalAlignment="Left"
                       Text="{x:Static p:Resources.BtnText}"
                       SnapsToDevicePixels="True"
                       RenderOptions.BitmapScalingMode="HighQuality">
                </TextBlock>
            </StackPanel>
        </Button>

        <!-- 一个空白的虚拟列,用于正确分配空间,使下一列水平右对齐。这一列将是空白的。 -->
        <ContentControl Grid.Column="4"/>

        <Button 
            Grid.Column="5"
            Height="25"
            Width="25"
            MaxHeight="25"
            MaxWidth="25"
            Margin="8,0,5,0"
            Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
            Command="{Binding BtnHlpClick}">
            <Image HorizontalAlignment="Center"
               VerticalAlignment="Center"
               Stretch="Uniform"
               SnapsToDevicePixels="True"
               RenderOptions.BitmapScalingMode="HighQuality"
               Source="{Binding ImageHelpIcon}"/>
        </Button>

        <StackPanel Grid.Column="6"
                x:Name="PlaceHolder"
                VerticalAlignment="Center"
                Margin="2,0,12,0"
                Width="27"
                Height="Auto">
            <Image
               HorizontalAlignment="Center"
               VerticalAlignment="Center"
               Stretch="Uniform"
               Height="20"
               Width="20"
               SnapsToDevicePixels="True"
               RenderOptions.BitmapScalingMode="HighQuality"
               Source="{Binding ImgThreeDotsIcon}">
                <Image.ContextMenu>
                    <ContextMenu Placement="Bottom" Background="#FFFFFF">
                        <MenuItem Header="{x:Static p:Resources.mnutext}" Command="{Binding MenuOnClick}"></MenuItem>
                    </ContextMenu>
                </Image.ContextMenu>
            </Image>
        </StackPanel>
    </Grid>
</Viewbox>

第一列的显示与否取决于条件。这里我只展示第一列不可见的用例。

上述代码生成以下结果(第一列不可见)。

期望的结果如下:

我希望最后两列(5和6)水平对齐到最右边,并在第3列和第5列之间增加额外的空白空间。请注意,第4列被用作虚拟列以创建额外的空白空间区域,其宽度在列定义中设置为"*"。

如何获得期望的结果?如果我删除Viewbox,那么我可以获得期望的结果,但我希望在添加Viewbox的情况下获得相同的结果。我需要Viewbox作为根元素,因为使用它可以使内容独立于屏幕分辨率和缩放(Viewbox会自动处理)。

英文:

I am using a Viewbox with Stretch set to Uniform in order to not distort the content when user switches between screen resolutions and scale in the OS.

Within the Viewbox I have a grid.
The grid has only 1 row and some columns.

&lt;Viewbox StretchDirection=&quot;Both&quot; 
Stretch=&quot;Uniform&quot;
HorizontalAlignment=&quot;Left&quot;
VerticalAlignment=&quot;Stretch&quot;&gt;
&lt;Grid Focusable=&quot;True&quot;
Height=&quot;Auto&quot;&gt;
&lt;Grid.ColumnDefinitions&gt;
&lt;!-- Animated image --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- Stack panel with icon and text --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- A vertical separator --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- A button --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- Empty dummy column to help distribute space correctly between columns so it will cause next columns to be horizontally right aligned. --&gt;
&lt;ColumnDefinition Width=&quot;*&quot; /&gt;
&lt;!-- Help button --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- Three dots button --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot;/&gt;
&lt;/Grid.ColumnDefinitions&gt;
&lt;StackPanel Grid.Column=&quot;0&quot;
Orientation=&quot;Horizontal&quot;
Visibility=&quot;{Binding Path=IsAnimatedImgVisible, Converter={StaticResource BoolToVisibility}}&quot;&gt;
&lt;v:UserControlAnimatedImg x:Name=&quot;UcSpinner&quot; VerticalAlignment=&quot;Center&quot; HorizontalAlignment=&quot;Left&quot;/&gt;
&lt;Label SnapsToDevicePixels=&quot;True&quot;
RenderOptions.BitmapScalingMode=&quot;HighQuality&quot;
VerticalAlignment=&quot;Center&quot; HorizontalAlignment=&quot;Left&quot;
Content=&quot;{Binding Path=StatusText}&quot;/&gt;
&lt;/StackPanel&gt;
&lt;StackPanel Grid.Column=&quot;1&quot;
Orientation=&quot;Horizontal&quot;&gt;
&lt;Image
Margin=&quot;10,5&quot;
Height=&quot;24&quot;
Width=&quot;24&quot;
MaxHeight=&quot;24&quot;
MaxWidth=&quot;24&quot;
VerticalAlignment=&quot;Center&quot;
HorizontalAlignment=&quot;Center&quot;
Stretch=&quot;None&quot; 
SnapsToDevicePixels=&quot;True&quot;
RenderOptions.BitmapScalingMode=&quot;HighQuality&quot;
Source=&quot;{Binding Path=Icon}&quot;/&gt;
&lt;Label 
VerticalAlignment=&quot;Center&quot;
HorizontalAlignment=&quot;Left&quot;
Content=&quot;{Binding Path=StatusTxt}&quot;
SnapsToDevicePixels=&quot;True&quot;
RenderOptions.BitmapScalingMode=&quot;HighQuality&quot;&gt;
&lt;/Label&gt;
&lt;/StackPanel&gt;
&lt;Separator Grid.Column=&quot;2&quot;
Margin=&quot;10,5,5,5&quot;
Height=&quot;26&quot;
Style=&quot;{StaticResource {x:Static ToolBar.SeparatorStyleKey}}&quot;&gt;
&lt;Button Grid.Column=&quot;3&quot;
Height=&quot;Auto&quot;
Width=&quot;150&quot;
Command=&quot;{Binding ButtonOnClick}&quot;&gt;
&lt;StackPanel Orientation=&quot;Horizontal&quot;&gt;
&lt;Image 
Height=&quot;24&quot;
Width=&quot;25&quot;
MaxHeight=&quot;24&quot;
MaxWidth=&quot;25&quot;
VerticalAlignment=&quot;Center&quot;
HorizontalAlignment=&quot;Center&quot;
Stretch=&quot;None&quot; 
SnapsToDevicePixels=&quot;True&quot;
RenderOptions.BitmapScalingMode=&quot;HighQuality&quot;
Source=&quot;{Binding ImageIcon}&quot;/&gt;
&lt;TextBlock
Margin=&quot;10,2,5,2&quot;
VerticalAlignment=&quot;Center&quot;
HorizontalAlignment=&quot;Left&quot;
Text=&quot;{x:Static p:Resources.BtnText}&quot;
SnapsToDevicePixels=&quot;True&quot;
RenderOptions.BitmapScalingMode=&quot;HighQuality&quot;&gt;
&lt;/TextBlock&gt;
&lt;/StackPanel&gt;
&lt;/Button&gt;
&lt;!-- Empty dummy space to help distribute space correctly between columns and
make next columns to be horizontally right aligned. This column will be blank   
space.--&gt;
&lt;ContentControl Grid.Column=&quot;4&quot;/&gt;
&lt;Button 
Grid.Column=&quot;5&quot;
Height=&quot;25&quot;
Width=&quot;25&quot;
MaxHeight=&quot;25&quot;
MaxWidth=&quot;25&quot;
Margin=&quot;8,0,5,0&quot;
Style=&quot;{StaticResource {x:Static ToolBar.ButtonStyleKey}}&quot;
Command=&quot;{Binding BtnHlpClick}&quot;&gt;
&lt;Image HorizontalAlignment=&quot;Center&quot;
VerticalAlignment=&quot;Center&quot;
Stretch=&quot;Uniform&quot;
SnapsToDevicePixels=&quot;True&quot;
RenderOptions.BitmapScalingMode=&quot;HighQuality&quot;
Source=&quot;{Binding ImageHelpIcon}&quot;/&gt;
&lt;/Button&gt;
&lt;StackPanel Grid.Column=&quot;6&quot;
x:Name=&quot;PlaceHolder&quot;
VerticalAlignment=&quot;Center&quot;
Margin=&quot;2,0,12,0&quot;
Width=&quot;27&quot;
Height=&quot;Auto&quot;&gt;
&lt;Image
HorizontalAlignment=&quot;Center&quot;
VerticalAlignment=&quot;Center&quot;
Stretch=&quot;Uniform&quot;
Height=&quot;20&quot;
Width=&quot;20&quot;
SnapsToDevicePixels=&quot;True&quot;
RenderOptions.BitmapScalingMode=&quot;HighQuality&quot;
Source=&quot;{Binding ImgThreeDotsIcon}&quot;&gt;
&lt;Image.ContextMenu&gt;
&lt;ContextMenu Placement=&quot;Bottom&quot; Background=&quot;#FFFFFF&quot;&gt;
&lt;MenuItem Header=&quot;{x:Static p:Resources.mnutext}&quot; Command=&quot;{Binding MenuOnClick}&quot;&gt;&lt;/MenuItem&gt;
&lt;/ContextMenu&gt;
&lt;/Image.ContextMenu&gt;
&lt;/Image&gt;
&lt;/StackPanel&gt;
&lt;/Viewbox&gt;

The first column is shown or not depending on a condition. Here I will show you only the use case with the first column not visible.

Above code produces below result (first column not visible):

视图框干扰网格列的水平对齐

And what I want, the expected result would be:

视图框干扰网格列的水平对齐

I want the last two columns (5 and 6) horizontally aligned to the rightmost and an extra blank space between columns 3 and 5. Note that column 4 is used as a dummy column to make this extra blank space area and its width is set to "*" in columndefinitions.

How can I get the expected result? If I remove the Viewbox then I get the expected result but I want to get the same result with the Viewbox added. I need the viewbox as root, i don't want to remove it, because using it I make content to be independent of the screen resolution and scaling (Viewbox does it automatically).

答案1

得分: 1

我认为你需要为你的网格设置一个明确的宽度。

或者至少一旦我设置了宽度,事情就会变得更好。

你没有向我们展示你的问题的最小复制品,所以我自己制作了一个。

我使用了一些矩形。

请注意,网格有一个固定的大小,以便测量排列知道一切应该有多大,以便*工作。

&lt;/Window.Resources&gt;
&lt;Viewbox&gt;
&lt;Grid Width=&quot;700&quot;&gt;
&lt;Grid.ColumnDefinitions&gt;
&lt;!-- 动画图像 --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- 带有图标和文本的堆栈面板 --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- 垂直分隔符 --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- 按钮 --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- 空的虚拟列,以帮助正确分配列之间的空间,使下一列水平右对齐。 --&gt;
&lt;ColumnDefinition Width=&quot;*&quot; /&gt;
&lt;!-- 帮助按钮 --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- 三个点的按钮 --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot;/&gt;
&lt;/Grid.ColumnDefinitions&gt;
&lt;Rectangle Width=&quot;100&quot; Height=&quot;50&quot; Grid.Column=&quot;0&quot;
Fill=&quot;Red&quot; Margin=&quot;4&quot;/&gt;
&lt;Rectangle Width=&quot;100&quot; Height=&quot;50&quot; Grid.Column=&quot;1&quot;
Fill=&quot;Red&quot; Margin=&quot;4&quot;/&gt;
&lt;Rectangle Width=&quot;100&quot; Height=&quot;50&quot; Grid.Column=&quot;7&quot;
Fill=&quot;Red&quot; Margin=&quot;4&quot;/&gt;
&lt;/Grid&gt;
&lt;/Viewbox&gt;
&lt;/Window&gt;

如果我减小大小,它仍然保持比例:

视图框干扰网格列的水平对齐

然后如果我将网格的宽度去掉:

视图框干扰网格列的水平对齐

这张图片是相同的Viewbox和700像素宽的网格,放在一个900像素宽的窗口里。

视图框干扰网格列的水平对齐

英文:

I think you need an explicit width for your grid.

Or at least once I set that, things work better.

You've not shown us a minimal reproduction of your issue so I made one myself.

I used some rectangles for this.

Note there is fixed size for the grid so measure arrange knows how big everything should be in order for * to work.

&lt;/Window.Resources&gt;
&lt;Viewbox&gt;
&lt;Grid Width=&quot;700&quot;&gt;
&lt;Grid.ColumnDefinitions&gt;
&lt;!-- Animated image --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- Stack panel with icon and text --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- A vertical separator --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- A button --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- Empty dummy column to help distribute space correctly between columns so it will cause next columns to be horizontally right aligned. --&gt;
&lt;ColumnDefinition Width=&quot;*&quot; /&gt;
&lt;!-- Help button --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
&lt;!-- Three dots button --&gt;
&lt;ColumnDefinition Width=&quot;Auto&quot;/&gt;
&lt;/Grid.ColumnDefinitions&gt;
&lt;Rectangle Width=&quot;100&quot; Height=&quot;50&quot; Grid.Column=&quot;0&quot;
Fill=&quot;Red&quot; Margin=&quot;4&quot;/&gt;
&lt;Rectangle Width=&quot;100&quot; Height=&quot;50&quot; Grid.Column=&quot;1&quot;
Fill=&quot;Red&quot; Margin=&quot;4&quot;/&gt;
&lt;Rectangle Width=&quot;100&quot; Height=&quot;50&quot; Grid.Column=&quot;7&quot;
Fill=&quot;Red&quot; Margin=&quot;4&quot;/&gt;
&lt;/Grid&gt;
&lt;/Viewbox&gt;

</Window>

If I choke down the size it still retains the proportions:

视图框干扰网格列的水平对齐

If I then take that width off the grid:

视图框干扰网格列的水平对齐

This picture is the same viewbox and 700 wide grid inside a 900px wide window

视图框干扰网格列的水平对齐

huangapple
  • 本文由 发表于 2023年2月8日 21:02:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75386209.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定