【问题标题】:WPF, XMAL percentage spacing gets calculated all wrongWPF,XAML 百分比间距计算全部错误
【发布时间】: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


【解决方案1】:

我会将其发布为答案,因为它满足了必要的设计需求,并将其标记为时间beeing的正确答案。 但是,这个答案并不能完全回答我的问题,因为它没有解释为什么以前的方法不起作用。

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

<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>

【讨论】:

    猜你喜欢
    • 2016-06-15
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 2021-01-10
    相关资源
    最近更新 更多