以此窗口为例:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" ResizeMode="NoResize" SizeToContent="WidthAndHeight" SnapsToDevicePixels="True">
<Grid Width="17" Margin="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<RepeatButton Grid.Row="0" SnapsToDevicePixels="True">
<Polyline RenderOptions.EdgeMode="Aliased" Stretch="Uniform" Margin="1" Fill="Red">
<Polyline.Points>
<Point X="0" Y="3" />
<Point X="3" Y="0" />
<Point X="6" Y="3" />
</Polyline.Points>
</Polyline>
</RepeatButton>
<RepeatButton Grid.Row="1" SnapsToDevicePixels="True">
<Polyline RenderOptions.EdgeMode="Aliased" Stretch="Uniform" Margin="1" Fill="Red">
<Polyline.Points>
<Point X="0" Y="3" />
<Point X="3" Y="0" />
<Point X="6" Y="3" />
</Polyline.Points>
</Polyline>
</RepeatButton>
</Grid>
</Window>
应用程序运行后,最上面的RepeatButton比底部的重要(因此顶部三角形也比底部三角形大)。为什么呢?
如果我创建4行相同的RepeatButtons,那么1-st和3-repeat RepeatButtons的大小相同,并且比第2和第4个RepeatButton大??
我认为这必定是WPF布局系统中的一个错误,但是如何解决这个问题呢?我不能使用固定的高度(这确实解决了问题),因为随着容器变大,我需要RepeatButtons和三角形strecth(我提供的示例简化为了显示问题,我知道我不能调整大小示例窗口...)。
回复本的评论:
是的,添加的样式三角形确实出现了9px和8px高(我可以完全通过RepeatButtons,只留下折线作为网格子项,这将产生相同的结果)。因为三角形是相等的,所以给网格宽度为17确实会导致高度变为17,这对于两个相等高度的三角形当然是不够的。
我实际上要做的是创建一个NumericUpDown控件。我发现默认情况下,spinner宽度为17,UserControl MinHeight为24,看起来非常好。唯一的问题是,如果我将这个UserControl放入网格中,那么顶部三角形总是将自己的1px推高到高,破坏了外观。无论我如何尝试与内部边距和填充物混合,顶部三角形总是比自己的高1px。所以本质上我想要的是拥有一个NumericUpDown,当放入Grid时,它不会扭曲自己。默认情况下,它应该从get go(没有Grid RowHeight =“Auto”)看起来很完美并且正确缩放(没有固定的高度)。它必须是可能的,因为通过物理查看像素,一切都可以很好地适应给定的尺寸。
这是我的NumericUpDown,我已经删除了所有非必要的东西,使它更紧凑:
<UserControl x:Class="HRS.NumericUpDown"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
MinWidth="40" MinHeight="24" Name="ucNUPD" Background="White" SnapsToDevicePixels="True">
<UserControl.Resources>
<Style TargetType="{x:Type RepeatButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Name="borderOuter" BorderThickness="1" BorderBrush="Red">
<Border Name="borderInner" BorderThickness="1" BorderBrush="Blue">
<ContentPresenter Margin="2,1" />
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="triangleStyle" TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Polyline HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Green" RenderOptions.EdgeMode="Aliased" Stretch="Uniform">
<Polyline.Points>
<Point X="0" Y="3" />
<Point X="3" Y="0" />
<Point X="6" Y="3" />
</Polyline.Points>
</Polyline>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Border BorderThickness="1" BorderBrush="#ABADB3">
<DockPanel>
<UniformGrid Margin="1" DockPanel.Dock="Right" Rows="2" MinWidth="17" Width="17">
<RepeatButton Name="repeatButtonUp" Grid.Row="0">
<ContentControl Style="{StaticResource triangleStyle}" />
</RepeatButton>
<RepeatButton Name="repeatButtonDown" Grid.Row="1">
<ContentControl Style="{StaticResource triangleStyle}" RenderTransformOrigin="0.5, 0.5">
<ContentControl.RenderTransform>
<ScaleTransform ScaleY="-1" />
</ContentControl.RenderTransform>
</ContentControl>
</RepeatButton>
</UniformGrid>
<TextBox BorderThickness="0" VerticalContentAlignment="Center" Text="0" />
</DockPanel>
</Border>
</UserControl>
以下是最终结果的图片:
(图片不符合100%,但您仍然可以看到所有相关细节。)
在右侧,您可以看到NumericUpDowns的放大。底部看起来正确,但仅仅因为网格的行高度设置为自动。最上面的一个是扭曲的,但默认情况下我希望它看起来与底部完全一样。
嗯...
我可能刚刚找到了一个可行的解决方案:
似乎通过将NumericUpDown中ContentPresenter的Margin设置为“3,1”,一切看起来都很完美。初步测试是非常有希望的,因为一切看起来都应该是它应该的方式...
我会测试一下tommorow,如果一切顺利,将Ben的答案标记为正确:)
答案 0 :(得分:4)
使用SizeToContent =“WidthAndHeight”,当你将Grid的宽度设置为17时,高度将为17.但是当17/2 = 8.5时,一行将为9(由于SnapsToDevicePixels =“True”而发生舍入)但是另一行将是8像素高。如果将宽度设置为18,则它们将相等。
我的理论证明:
<Grid Width="17" Margin="0">
<Grid.Resources>
<Style TargetType="{x:Type RepeatButton}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<ContentPresenter Margin="0"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<RepeatButton Grid.Row="0" SnapsToDevicePixels="True">
<Polyline RenderOptions.EdgeMode="Aliased" Stretch="Uniform" Margin="0" Fill="Red">
<Polyline.Points>
<Point X="0" Y="3" />
<Point X="3" Y="0" />
<Point X="6" Y="3" />
</Polyline.Points>
</Polyline>
</RepeatButton>
<RepeatButton Grid.Row="1" SnapsToDevicePixels="True">
<Polyline RenderOptions.EdgeMode="Aliased" Stretch="Uniform" Margin="0" Fill="Red">
<Polyline.Points>
<Point X="0" Y="3" />
<Point X="3" Y="0" />
<Point X="6" Y="3" />
</Polyline.Points>
</Polyline>
</RepeatButton>
使用此片段,您将获得一个高度为9像素的三角形,以及一个高度为8像素的三角形。
但如果你想要一个解决方案,试试这个:
<RepeatButton Grid.Row="1" SnapsToDevicePixels="True" Height="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth}" >
<Polyline RenderOptions.EdgeMode="Aliased" Stretch="Uniform" Margin="0" Fill="Red">
<Polyline.Points>
<Point X="0" Y="3" />
<Point X="3" Y="0" />
<Point X="6" Y="3" />
</Polyline.Points>
</Polyline>
</RepeatButton>
这样按钮的宽度和高度就相等。
如果认为你也可以写一个小转换器,那可能会做一些讨厌的事情:
<RepeatButton Grid.Row="1" SnapsToDevicePixels="True" Height="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth, Converter={StaticResource TriangleWidthConverter}}" >
<Polyline RenderOptions.EdgeMode="Aliased" Stretch="Uniform" Margin="0" Fill="Red">
<Polyline.Points>
<Point X="0" Y="3" />
<Point X="3" Y="0" />
<Point X="6" Y="3" />
</Polyline.Points>
</Polyline>
</RepeatButton>
public class TriangleWidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
int width = 0;
if (int.TryParse(value.ToString(), out width))
return width + 1; // Do some fun here.
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
我希望这些会有所帮助。
答案 1 :(得分:0)
不知道你为什么会看到这种行为,但这可能会解决这个问题:尝试将每行的高度设置为.5 *如果你有2行,或者.25 *如果你有4行(或.1 *如果你有10行,等等。)