英文:
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.
<Viewbox StretchDirection="Both"
Stretch="Uniform"
HorizontalAlignment="Left"
VerticalAlignment="Stretch">
<Grid Focusable="True"
Height="Auto">
<Grid.ColumnDefinitions>
<!-- Animated image -->
<ColumnDefinition Width="Auto" />
<!-- Stack panel with icon and text -->
<ColumnDefinition Width="Auto" />
<!-- A vertical separator -->
<ColumnDefinition Width="Auto" />
<!-- A button -->
<ColumnDefinition Width="Auto" />
<!-- Empty dummy column to help distribute space correctly between columns so it will cause next columns to be horizontally right aligned. -->
<ColumnDefinition Width="*" />
<!-- Help button -->
<ColumnDefinition Width="Auto" />
<!-- Three dots button -->
<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>
<!-- 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.-->
<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>
</Viewbox>
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
我认为你需要为你的网格设置一个明确的宽度。
或者至少一旦我设置了宽度,事情就会变得更好。
你没有向我们展示你的问题的最小复制品,所以我自己制作了一个。
我使用了一些矩形。
请注意,网格有一个固定的大小,以便测量排列知道一切应该有多大,以便*工作。
</Window.Resources>
<Viewbox>
<Grid Width="700">
<Grid.ColumnDefinitions>
<!-- 动画图像 -->
<ColumnDefinition Width="Auto" />
<!-- 带有图标和文本的堆栈面板 -->
<ColumnDefinition Width="Auto" />
<!-- 垂直分隔符 -->
<ColumnDefinition Width="Auto" />
<!-- 按钮 -->
<ColumnDefinition Width="Auto" />
<!-- 空的虚拟列,以帮助正确分配列之间的空间,使下一列水平右对齐。 -->
<ColumnDefinition Width="*" />
<!-- 帮助按钮 -->
<ColumnDefinition Width="Auto" />
<!-- 三个点的按钮 -->
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Rectangle Width="100" Height="50" Grid.Column="0"
Fill="Red" Margin="4"/>
<Rectangle Width="100" Height="50" Grid.Column="1"
Fill="Red" Margin="4"/>
<Rectangle Width="100" Height="50" Grid.Column="7"
Fill="Red" Margin="4"/>
</Grid>
</Viewbox>
</Window>
如果我减小大小,它仍然保持比例:
然后如果我将网格的宽度去掉:
这张图片是相同的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.
</Window.Resources>
<Viewbox>
<Grid Width="700">
<Grid.ColumnDefinitions>
<!-- Animated image -->
<ColumnDefinition Width="Auto" />
<!-- Stack panel with icon and text -->
<ColumnDefinition Width="Auto" />
<!-- A vertical separator -->
<ColumnDefinition Width="Auto" />
<!-- A button -->
<ColumnDefinition Width="Auto" />
<!-- Empty dummy column to help distribute space correctly between columns so it will cause next columns to be horizontally right aligned. -->
<ColumnDefinition Width="*" />
<!-- Help button -->
<ColumnDefinition Width="Auto" />
<!-- Three dots button -->
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Rectangle Width="100" Height="50" Grid.Column="0"
Fill="Red" Margin="4"/>
<Rectangle Width="100" Height="50" Grid.Column="1"
Fill="Red" Margin="4"/>
<Rectangle Width="100" Height="50" Grid.Column="7"
Fill="Red" Margin="4"/>
</Grid>
</Viewbox>
</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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论