【发布时间】:2021-03-10 02:44:19
【问题描述】:
总之
我的理解是,通过在 xaml 中使用 *,您应该获得“固定”百分比。但是,即使将两个网格添加到具有完全相同的行和列定义的控件,计算似乎也不同。
tl;博士
我想做的事
我想创建一个带有画布或按钮的用户控件来打开颜色选择器。在设计该控件时,我偶然发现了一个我自己无法解释的问题。
控件的左侧应该几乎是右侧的完整镜像副本,但有一点不同:最外面的线条应该在外观上略有不同。虽然左行应该很短,但右行应该放在控件的最底部以便封装文本块。
我的方法
为了实现这一点,我创建了一个“主”网格来承载三个元素(左手设计网格、打开颜色选择器的中心控件和右手网格)。我添加了由网格封装的中心控件,只是为了与我在左侧和右侧的方法保持一致。
继续,我为提到的左侧和右侧添加了两个网格,并为它们提供了完全相同的行和列定义。认为这样可以解决问题,我添加了几行来将希望的设计添加到控件中。
问题
我很快注意到,两条水平线不匹配。线条之间有几个像素,所以我尝试使用布局来找出导致该问题的原因。
“解决方案”
除了最右边的线外,似乎一切都正常。每当它的Grid.RowSpan 设置为 4,这意味着它将延伸到控件的底部,它会与百分比的间距混淆。出于某种原因,我无法理解它似乎改变了Grid.RowDefinitions 计算的百分比
只需将最右边的行的Grid.ColumnSpan="4" 设置为Grid.ColumnSpan="3" 即可修复间距,将最外左行的Grid.ColumnSpan="4" 更改为Grid.ColumnSpan="3" 也可以正确更改间距。
一个新问题
这种尝试显然修复了间距,但确实引入了一个新问题:使用这两个修复中的任何一个修复的用户控件的设计都发生了变化。要么两条线都必须放在控件的最底部,要么两条线都必须很短。
我真的希望这两条线略有不同。此外,中心的两条垂直线似乎根本不会对间距产生负面影响,即使它们也跨越了讨论的行。
另一种解决方案?
我只是简单地将所有线条更改为具有黑色背景颜色的画布。这确实解决了问题,并且一切都正确呈现。但是我坐在这里,不明白为什么会首先出现这个问题。 我希望了解导致百分比计算发生变化的原因,以提高我在使用 XAML 设计 UI 方面的知识。
但是,控件预览现在似乎可以工作,但是当另一个控件“使用”时(意味着我已将该控件添加到另一个控件),似乎整个间距又错了,就像我在'用过线条。
新的罪魁祸首
在玩耍时,我注意到在删除文本框时间距会再次正确,即使被另一个控件占用也是如此。不过,我在这里的问题是要了解这可能是一个问题,即使百分比都应该相同,水平线没有差异的空间。
我自然想知道负边距是否会导致错误(这是为了让 TextBlock 更靠近线条)。但是无论有没有余量,错误仍然存在。
一个更一般的问题
我知道,关于最佳方法和实践的一般性问题在这里不太受欢迎,但请让我至少询问有关如何使用 XAML 设计编写良好的控件的资源。过去几周我阅读的所有内容对我有很大帮助,但我似乎经常会偶然发现许多问题。
我无法告诉您我在 Microsoft 文档网站上的什么地方看到的,但它明确指出应该尽量避免使用画布。也许我误解了,但是,在我看来,在这里使用画布似乎是一种廉价的技巧,可以避免我在线条上遇到的简单问题。
此外,如果有人对如何更改控件布局以实现所需输出有任何想法,请告诉我。提前感谢您抽出时间阅读本文。
资源
用户控制线
问题:显示水平线略微偏离
<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>
User-control as displayed in designer with horizontal lines being off
使用画布进行用户控制
问题:在预览中似乎可以工作,但添加到另一个控件时会计算错误
<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>
User-control with canvases instead of lines being displayed correctly in designer
User-control displayed wrong after being added to another control
【问题讨论】:
-
为了让您知道,我也尝试过使用单个网格。然而,那里的计算也有错误。网格具有大小为 *、1、* 的三个行定义。由于某种奇怪的原因,高度设置为 1px 的行显示得比这大得多。
标签: wpf xaml user-controls