【问题标题】:Properly sizing a WPF control to always stay the same size as its parent正确调整 WPF 控件的大小,使其始终保持与其父控件相同的大小
【发布时间】:2017-07-28 13:35:40
【问题描述】:

我正在尝试为一个简单的 WPF 计算器应用程序创建一个按钮网格,但我无法正确绘制按钮。

我在按钮 (btnPlusMinus) 内使用网格 (grdPlusMinus) - 在整个控件网格 (grdControls) 内 - 这样我就可以制作一个顶部带有简单标签的椭圆按钮。 Ellipse 应该填充 Button 的可见部分。

使用下面的代码时,无论窗口大小如何调整,椭圆的底部和右侧都被“截断”。椭圆总是成比例的,但它永远不会完全显示。 当我将 grdPlusMinus 的 Width 和 Height 重置为 Auto(通过 VS UI,而不是在代码中)时,它们都设置为 1,结果 grdPlusMinus - 以及其中的所有内容 - 缩小到单个像素。

我可能在基本层面上做了一些非常愚蠢的事情,但我就是想不出它是什么。 我尝试了所有不同类型的绑定和设置 - 例如绑定到 Width 而不是 ActualWidth 等 - 但我无法弄清楚我做错了什么。 我认为这可能是因为边距,但完全删除边距并没有太大改变问题。

谁能指出我做错了什么? (我在 Kaxaml 中尝试了 XAML 的变体并遇到了同样的问题。)

如果有更好的方法 - 总体而言 - 我正在尝试做的事情,那么我想听听,但我想在尝试其他任何事情之前知道这有什么问题。 (我的最终意图是将每个按钮的高度和宽度设置为按钮的最小尺寸,以便它始终显示为按钮中心的一个圆圈,但这是以后的事情,除非这些额外信息允许更好的解决方案。)

<Window x:Class="Calc.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Calc"
        mc:Ignorable="d"
        Title="MainWindow" Height="651.5" Width="525" WindowStartupLocation="CenterScreen">
    <Grid x:Name="grdControls">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button x:Name="btnPlusMinus" Grid.Row="5" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="4">
            <Grid x:Name="grdPlusMinus" Width="{Binding ActualWidth, ElementName=btnPlusMinus, Mode=OneWay}" Height="{Binding ActualHeight, ElementName=btnPlusMinus, Mode=OneWay}">
                <Ellipse x:Name="ellipse" Stroke="#FF39A8DC" Fill="#FFA0D2E2"/>
                <Label x:Name="label" Content="XXX" HorizontalAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" Foreground="#FF0A263A" HorizontalContentAlignment="Center"/>
            </Grid>
        </Button>

    </Grid>
</Window>

【问题讨论】:

  • 你想在这里做什么一切都错了?
  • 这里有一个关于如何在 xaml 中自定义 button 的教程。
  • 移除grdPlusMinus的宽度和高度定义。你不需要它们。
  • 感谢@FilipCordas 的链接,但我想知道这种情况下的具体问题是什么,这样我就可以了解如果将来再次出现该问题如何解决。
  • @XAMlMAX 删除宽度和高度定义只是将椭圆缩小到标签的大小。我希望椭圆填充按钮。

标签: c# .net wpf


【解决方案1】:

这就像问为什么当我从飞机上跳下来时我的雨伞不起作用。您的问题的简单答案不打算以这种方式使用。 XAML 拥有有史以来最好的定位系统之一,因此使用起来很容易(性能可能不太好,但您不必担心)。

 <Grid>
        <Grid.RowDefinitions>
            <!-- For what you are doing the multiple rows are not needed you can use relative size they work by adding all the values in rows (1+5) and deviding them by it
            so 5* is 5/6 of parant 
            and 1* is 1/6 of parent height
            -->
            <RowDefinition Height="5*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <!-- works the same for columns -->
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="4*"/>
        </Grid.ColumnDefinitions>
        <Button Grid.Row="1">
            <Button.Style>
                <!-- this is the template you button will use it's best to use global styles but you can inline it as well-->
                <Style TargetType="Button">
                    <Setter Property="Template" >
                        <Setter.Value>
                            <ControlTemplate TargetType="Button">
                                <Grid>
                                    <Ellipse Stroke="#FF39A8DC" Fill="#FFA0D2E2"/>
                                    <!-- used to show what ever is in you inner button content it can be an image or textblock or anything -->
                                    <ContentPresenter 
                                        Content="{TemplateBinding Content}" 
                                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />

                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Button.Style>
            <Label Content="XXX"></Label>
        </Button>
    </Grid>

这里有更多关于 grid 工作原理的信息。

【讨论】:

  • 谢谢@Filip Cordas。我不知道为什么你改变了外部网格定义,因为我有我想要的(据我所知)但你的解决方案有效,我也可以在椭圆周围添加边距,以便其他按钮 - 稍后添加时 -不要互相“接触”。好的。转换为使用应用程序样式也使窗口标记非常简单。这并不像我最初想象的那么容易。看起来我需要了解更多关于 ControlTemplates 和 ContentPresenters 的信息。学习经验的所有部分。无论如何,再次感谢。
  • @GarryP 也可以尝试访问this 链接,它有更多关于布局系统的信息。整个网站真的很棒,所以如果你有时间看看上面的所有课程。
  • 谢谢@Filip Cordas 在我开始犯更多错误/假设之前,我真的需要让自己更加熟悉这整个领域。看起来很简单,但显然我需要先了解一些规则。一旦它最终“点击”,我将能够更好地开始正确地做事。
【解决方案2】:

很抱歉,我无法解释为什么会发生这种情况,但我发现可以通过将按钮行替换为以下内容来实现您想要的结果:

    <Button x:Name="btnPlusMinus" Grid.Row="5" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}" Padding="-5">

注意边距被替换为 padding="-5"

【讨论】:

  • 您的解决方案看起来很有效——在这个特定的例子中——但它似乎也有点像“创可贴”,它覆盖了问题而不是修复它。每次手动设置填充以否定边距似乎是错误的做法。谢谢,但我会等着看是否有不需要这种解决方法的答案。
  • 我同意你的看法。希望您能得到正确的解释/答案或弄清楚。周末愉快。
猜你喜欢
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多