WPF,XMAL百分比间距计算错误



简而言之

我的理解是,通过在xaml中使用*,你应该得到";固定的";百分比。然而,即使将两个网格添加到具有完全相同的Row和Column定义的控件中,计算似乎也有所不同。

tl;dr

我想做什么

我想创建一个带有画布或按钮的用户控件来打开颜色选择器。在设计该控件时,我偶然发现了一个无法解释自己的问题。

控件的左手边应该几乎是右手边的一个完整镜像副本,但有一个小的差异:最外面的线条在外观上应该略有不同。左边的行应该很短,右边的行应该放在控件的最底部,以便封装文本块。

我的方法

为了实现这一点,我创建了一个";主";网格来承载三个元素(左侧设计网格、打开颜色选择器的中心控件和右侧网格)。我添加了由网格封装的中控,只是为了与我在左手边和右手边的方法保持一致。

接下来,我为提到的左侧和右侧添加了两个网格,并为它们提供了完全相同的行和列定义。我想这就行了,我添加了几行,将所需的设计添加到控件中。

问题

我很快就注意到,这两条水平线不匹配。线条之间有几个像素,所以我试着摆弄一下布局,看看是什么导致了这个问题。

"解决方案">

除了最右边的一行外,似乎所有的东西都表现得很正确。每当其Grid.RowSpan设置为4(意味着它将延伸到控件的底部)时,它就会扰乱百分比的间距。出于某种原因,我无法理解它似乎改变了Grid.RowDefinition的计算的百分比

简单地将最右边的行的Grid.ColumnSpan="4"设置为Grid.ColumnSpan="3"确实可以固定间距,将最左边的行上的Grid.ColumnSpan="4"更改为Grid.ColumnSpan="3"也可以正确地更改间距。

一个新问题

这种尝试显然修复了间距,但确实引入了一个新问题:使用这两种修复中的任何一种的用户控件的设计都发生了变化。要么两行都必须放在控件的最底部,要么两行必须短。

我真的希望这两行稍微有点不同。此外,中心的两条垂直线似乎根本不会对间距产生负面影响,即使它们也跨越了所讨论的行。

另一个解决方案

我只是简单地把所有的线条都改成了黑色背景的画布。这确实解决了问题,而且一切都呈现得很正确。但我坐在这里,一开始就不明白为什么会出现这个问题我想了解是什么原因改变了百分比的计算,以提高我在使用XAML设计UI方面的知识。

然而,控件预览现在似乎可以工作,但当"消耗的";通过另一个控件(意味着我已经将该控件添加到另一个控制器中),整个间距似乎又错了,就像我使用线条时一样。

一个新的罪魁祸首

在玩的时候,我注意到当删除文本框时,即使被另一个控件占用,间距也会再次正确。尽管如此,我在这里的问题是理解这怎么会成为一个问题,尽管百分比应该都是一样的,没有留下水平线不同的空间。

很自然,我想知道负边距是否会导致错误(这是为了让TextBlock移近行)。但无论有没有余量,误差仍然存在。

一个更普遍的问题

我知道,关于最佳方法和实践的一般性问题在这里不太受欢迎,但请让我至少询问有关如何使用XAML设计编写良好的控件的资源。过去几周我读到的东西对我帮助很大,但我似乎经常会遇到很多问题。

我无法告诉你我在微软文档网站上读到过这篇文章,但它明确指出,应该尽量避免使用画布。也许我误解了,然而,在我看来,在这里使用画布似乎是一种廉价的技巧,可以避免我在线条上遇到的简单问题。

此外,如果有人对如何更改控件布局以实现所需输出有任何想法,请告诉我。提前感谢您花时间通读这篇文章。

资源

带线路的用户控制

问题:显示的水平线稍微偏离

<UserControl ...
mc:Ignorable="d" d:DesignHeight="50"  d:DesignWidth="400"
MinHeight="50">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="54"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- left hand side grid-->
<Grid Grid.Column="0"
Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="1"/>
<RowDefinition Height="*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Line Grid.Column="0" Grid.ColumnSpan="1"
Grid.Row="1" Grid.RowSpan="3"
X1="0" X2="0"
Y1="0" Y2="1"
Stroke="Black"
StrokeThickness="1"
Stretch="Uniform"
SnapsToDevicePixels="True"/>
<Line Grid.Column="0" Grid.ColumnSpan="3"
Grid.Row="2" Grid.RowSpan="1"
X1="0" X2="1"
Y1="0" Y2="0"
Stroke="Black"
StrokeThickness="1"
Stretch="Uniform"
SnapsToDevicePixels="True"/>
<Line Grid.Column="2" Grid.ColumnSpan="1"
Grid.Row="0" Grid.RowSpan="5"
X1="0" X2="0"
Y1="0" Y2="1"
Stroke="Black"
StrokeThickness="1"
Stretch="Uniform"
SnapsToDevicePixels="True"/>
</Grid>
<!-- middle grid -->
<Grid Grid.Column="1"
Grid.Row="0">
<Canvas Margin="2, 0"
Background="Red"/>
</Grid>
<!-- right hand side grid-->
<Grid Grid.Column="2"
Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="1"/>
<RowDefinition Height="*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Line Grid.Column="0" Grid.ColumnSpan="1"
Grid.Row="0" Grid.RowSpan="5"
X1="0" X2="0"
Y1="0" Y2="1"
Stroke="Black"
StrokeThickness="1"
Stretch="Uniform"
SnapsToDevicePixels="True"/>
<Line Grid.Column="0" Grid.ColumnSpan="3"
Grid.Row="2" Grid.RowSpan="1"
X1="0" X2="1"
Y1="0" Y2="0"
Stroke="Black"
StrokeThickness="1"
Stretch="Uniform"
SnapsToDevicePixels="True"/>
<Line Grid.Column="2" Grid.ColumnSpan="1"
Grid.Row="1" Grid.RowSpan="4"
X1="0" X2="0"
Y1="0" Y2="1"
Stroke="Black"
StrokeThickness="1"
Stretch="Uniform"
SnapsToDevicePixels="True"/>
<TextBlock Grid.Column="1"
Grid.Row="3" Grid.RowSpan="2"
Text="Prefered Color"
FontSize="20"
FontFamily="Segoe UI Light"
Typography.Capitals="SmallCaps"
Foreground="Black"
HorizontalAlignment="Right"
Margin="4, -3, 4, 0"/>
</Grid>
</Grid>
</UserControl>

用户控制显示在设计器中,水平线关闭

Canvass 的用户控制

问题:在预览中似乎有效,但添加到另一个控制时会被误判

<UserControl ...
mc:Ignorable="d" d:DesignHeight="50"  d:DesignWidth="400"
MinHeight="50">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="54"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- left hand side grid-->
<Grid Grid.Column="0"
Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="1"/>
<RowDefinition Height="*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Canvas Grid.Column="0" Grid.ColumnSpan="1"
Grid.Row="1" Grid.RowSpan="3"
Background="Black"
SnapsToDevicePixels="True"/>
<Canvas Grid.Column="0" Grid.ColumnSpan="3"
Grid.Row="2" Grid.RowSpan="1"
Background="Black"
SnapsToDevicePixels="True"/>
<Canvas Grid.Column="2" Grid.ColumnSpan="1"
Grid.Row="0" Grid.RowSpan="5"
Background="Black"
SnapsToDevicePixels="True"/>
</Grid>
<!-- middle grid -->
<Grid Grid.Column="1"
Grid.Row="0">
<Canvas Margin="2, 0"
Background="Red"/>
</Grid>
<!-- right hand side grid-->
<Grid Grid.Column="2"
Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="1"/>
<RowDefinition Height="*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Canvas Grid.Column="0" Grid.ColumnSpan="1"
Grid.Row="0" Grid.RowSpan="5"
Background="Black"
SnapsToDevicePixels="True"/>
<Canvas Grid.Column="0" Grid.ColumnSpan="3"
Grid.Row="2" Grid.RowSpan="1"
Background="Black"
SnapsToDevicePixels="True"/>
<Canvas Grid.Column="2" Grid.ColumnSpan="1"
Grid.Row="1" Grid.RowSpan="4"
Background="Black"
SnapsToDevicePixels="True"/>
<TextBlock Grid.Column="1"
Grid.Row="3" Grid.RowSpan="2"
Text="Prefered Color"
FontSize="20"
FontFamily="Segoe UI Light"
Typography.Capitals="SmallCaps"
Foreground="Black"
HorizontalAlignment="Right"
Margin="4, 0, 4, 0"/>
</Grid>
</Grid>
</UserControl>

使用画布而不是线条在设计器中正确显示的用户控件

用户控件添加到另一个控件后显示错误

我将把它作为答案发布,因为它满足了必要的设计需求,并将其标记为正确答案然而,这个答案并不能完全统计我的问题,因为它不能解释为什么以前的方法不起作用。

因此,请随意添加答案,我会选择解释问题的答案作为正确答案。

<UserControl ...
mc:Ignorable="d" d:DesignHeight="50"  d:DesignWidth="400"
MinHeight="50">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="1"/>
<RowDefinition Height="*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="1"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="3"
Grid.Row="0" Grid.RowSpan="5"
Margin="4,0"
Background="Red"
BorderThickness="0"
Command="{Binding ColorClick}">
</Button>
<TextBlock Grid.Column="5"
Grid.Row="4" Grid.RowSpan="2"
Text="Prefered Color"
FontSize="20"
FontFamily="Segoe UI Light"
Typography.Capitals="SmallCaps"
Foreground="Black"
HorizontalAlignment="Right"
Margin="4, 0, 4, 0"/>
<Canvas Grid.Column="0"
Grid.Row="1" Grid.RowSpan="3"
Background="Black"/>
<Canvas Grid.Column="1"
Grid.Row="2" Grid.RowSpan="1"
Background="Black"/>
<Canvas Grid.Column="2"
Grid.Row="0" Grid.RowSpan="5"
Background="Black"/>
<Canvas Grid.Column="4"
Grid.Row="0" Grid.RowSpan="5"
Background="Black"/>
<Canvas Grid.Column="5"
Grid.Row="2" Grid.RowSpan="1"
Background="Black"/>
<Canvas Grid.Column="6"
Grid.Row="1" Grid.RowSpan="5"
Background="Black"/>
</Grid>
</UserControl>

最新更新