WPF似乎是对角分割我的控件.我究竟做错了什么?蓝色按钮上的问题更清晰,但右侧的问题仍然明显.

奇怪的是,kaxaml正确地呈现按钮.WPF设计师似乎永远不会.当我在独立的'WpfApplication1'中运行示例代码时,它正确呈现.但是,在我的应用程序中,我得到了对角线'切割'.值得一提的是,在运行时WPF似乎不能始终如一地应用切片效果,有时它们会正确呈现!
更新1:
线索!它只是影响按钮!当我创建一个独立的Border并将标签作为其内容时,没有切片效果?!?!! 所以这不是xaml本身,而是与按钮有关的神奇之处?!大声思考,与未完全覆盖默认Button模板有关的事情?
更新2:
嗯,这一点变得更奇怪了.这与阴影效果有关.似乎要绘制的第一种具有效果的控件(BitmapEffect或wpf 4.0 Effect)与所有其他控件实例一样被拆分.例如,这是一个带有可爱红色阴影的DatePicker,它对角分割DatePicker控件,之后按钮很好,尽管也有效果应用于它.

如果我不应用效果,则不会分割任何控件.如果我绘制一个具有效果的控件,则此控件将被拆分,并且后续的不同类型的控件也可以.但是,如果您有两个或三个相同类型的控件,它们也会被拆分.即,如果按钮被拆分,页面上的所有按钮也将被拆分.
这必须与我的GPU或图形驱动程序有关.我今天早上更新了它们,但没有快乐.(我使用的是Radeon Mobility HD 5650,v 8.683.2.0).如果这个问题与我的电脑隔离,我认为这不是世界末日.可能,我可以通过在每个页面顶部的随机路径像素上绘制透明效果或其他东西来打败它自己的游戏......
更新3
噢亲爱的.我现在在另一台PC上重现了这个,所以它不是我的显卡或驱动程序.
<StackPanel.Resources>
<!-- Background for button when IsDefault true"-->
<LinearGradientBrush x:Key="DefaultButtonFill" StartPoint="0.5, 0" EndPoint="0.5, 1">
<GradientStop Color="#FFDFEDEC" Offset="0"/>
<GradientStop Color="#FF92B1E3" Offset="0.4"/>
<GradientStop Color="#FF749EE0" Offset="0.5"/>
<GradientStop Color="#94DDF6" Offset="1"/>
</LinearGradientBrush>
<!-- default button background -->
<LinearGradientBrush x:Key="NotDefaultButtonFill" StartPoint="0.5, 0" EndPoint="0.5, 1">
<GradientStop Color="#FFEFEFF5" Offset="0"/>
<GradientStop Color="#FFE1E1E6" Offset="0.4"/>
<GradientStop Color="#FFC7CBD0" Offset="0.5"/>
<GradientStop Color="#FFE8ECEE" Offset="1"/>
</LinearGradientBrush>
<Style TargetType="Button">
<Setter Property="FontSize" Value="14"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="border"
CornerRadius="12"
Background="{StaticResource NotDefaultButtonFill}"
Padding="25 8"
Margin="10"
Cursor="Hand">
<Border.BitmapEffect>
<DropShadowBitmapEffect x:Name="shadow" Direction="280" Color="Black" ShadowDepth="2" Opacity=".6"/>
</Border.BitmapEffect>
<!--
<Border.Effect>
<DropShadowEffect x:Name="shadow" Direction="280" Color="Black" ShadowDepth="2" Opacity=".6"/>
</Border.Effect>-->
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefault" Value="True">
<Setter TargetName="border" Property="Background" Value="{StaticResource DefaultButtonFill}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="border" Property="Background" Value="LightGray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<StackPanel Orientation="Horizontal">
<Button>Normal</Button>
<Button IsDefault="True">IsDefault</Button>
</StackPanel>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
这是由于 WPF 和 ATI 图形驱动程序之间的一些微妙交互引起的错误。当对未完全位于像素边界上的元素使用 DropShadowEffect 时,似乎会发生这种情况。
如果您在有问题的元素上设置 UseLayoutRounding="True" (或以适当的样式),似乎可以在很多情况下解决问题,但不是全部。要做的另一件事是确保您没有故意将元素定位在半像素处(例如,通过使用分数边距 - 如果您在 Expression Blend 中移动元素,则可能会发生这种情况)。
这是一个简单的重现案例:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Width" Value="28"/>
<Setter Property="Height" Value="28"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" Background="Transparent">
<Grid Margin="{TemplateBinding Padding}">
<ContentPresenter x:Name="contentPresenter" VerticalAlignment="Center"
HorizontalAlignment="Center">
<ContentPresenter.Effect>
<DropShadowEffect BlurRadius="13" Color="Black" Opacity="1" ShadowDepth="0" Direction="0"/>
</ContentPresenter.Effect>
</ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<Button x:Name="MinimizeButton"
Style="{StaticResource ButtonStyle}">
<Rectangle x:Name="MinimizeIcon"
Width="11"
Height="2"
HorizontalAlignment="Center"
Margin="0,7,0,0"
VerticalAlignment="Bottom"
Stroke="Gray"
StrokeThickness="2"/>
</Button>
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
如果将其粘贴在Kaxaml中并移动缩放滑块,当缩放设置为 150 时,您应该会看到分割出现。
如果添加<Setter Property="UseLayoutRounding" Value="True"/>到按钮样式,缩放级别 150 会正确渲染,但在缩放级别 300 时会出现分割。
这就是为什么我说我的解决方法并不适用于所有情况 - 如果您只需要以一种固定尺寸显示内容,则 UseLayoutRounding 可能会隐藏该尺寸的问题,但如果您的应用程序中有缩放功能,有时您可能仍然会遇到问题。
ATI在Microsoft 论坛上对此问题的看法如下:
根本原因是,WPF 4.0 在使用 DX9 API 时将使用 DX10 样式纹理坐标寻址,通过点过滤器(舍入到最近的值)渲染文本。我们遵循 DX9 规则(截断到最近的),因为这是 DX9 驱动程序。如果我们强制硬件使用 DX10 风格的纹理坐标,问题就会消失。然而,我认为微软应该遵循他们自己的规则,在使用 DX9 API 的同时使用 DX9 风格的纹理坐标寻址。”
如果您也能重现此问题,请前往我在 Connect 上添加的问题中投票,以便我们能够解决此问题 - 尽管我不抱太大希望;微软对类似问题的回应称,他们认为暂时可以接受该解决方案。