如何防止DataGrid裁剪与第一行重叠的图像?

时间:2019-01-07 10:50:12

标签: wpf datagrid clip

我们有一个标准的Validation.ErrorTemplate,它绘制一个红色边框并在带有验证错误的控件的右上角显示一个错误图标。除了在数据网格的第一行中(该图像被网格的ScrollViewer剪切(我认为))之外,这在任何地方都适用。

Clipped error icon

理想情况下,顶部错误图标将完整显示,而底部错误图标将直到该行可见后才会显示。

下面是一个示例,该示例以我可以管理的最少代码重现了该问题:

<Window x:Class="WpfClippedAdorner.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:draw="clr-namespace:System.Drawing;assembly=System.Drawing"
    xmlns:valueConverters="clr-namespace:WpfClippedAdorner.ValueConverters"
    mc:Ignorable="d"
    Title="MainWindow" Height="150" Width="200">
<Grid>
    <Grid.Resources>
        <valueConverters:IconToImageSourceConverter x:Key="IconToImageSourceConverter" />
    </Grid.Resources>
    <DataGrid AutoGenerateColumns="False" Height="75" Width="150" 
              ClipToBounds="False">
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <DockPanel LastChildFill="true">
                            <Border BorderBrush="red" BorderThickness="1" >
                                <TextBlock Text="{Binding Text}" />
                            </Border>
                            <Image Source="{Binding Source={x:Static draw:SystemIcons.Error}, Converter={StaticResource IconToImageSourceConverter}, Mode=OneWay}" 
                                   Margin="-10,-8,0,0" Height="16" Width="16" VerticalAlignment="Top"/>
                        </DockPanel>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
        <DataGrid.Items>
            <TextBlock Text="Test1"/>
            <TextBlock Text="Test2"/>
            <TextBlock Text="Test3"/>
            <TextBlock Text="Test4"/>
        </DataGrid.Items>
    </DataGrid>
</Grid>
</Window>

请注意,ClipToBounds设置为False,但不能解决问题。 我也尝试过提取DataGrid控件模板并在各处设置ClipToBounds =“ False”,而没有任何可见效果。

这是我用来显示图标的值转换器,以防您要重新创建测试项目。

namespace WpfClippedAdorner.ValueConverters
{
using System;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;

/// <summary>
/// Converts a windows icon to an image source that can be used in WPF
/// </summary>
/// <seealso cref="System.Windows.Data.IValueConverter" />
public class IconToImageSourceConverter : IValueConverter
{
    /// <inheritdoc />
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var icon = value as Icon;
        if (icon == null)
        {
            Trace.TraceWarning("Attempted to convert {0} instead of Icon object in IconToImageSourceConverter", value);
            return null;
        }

        ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon(
            icon.Handle,
            Int32Rect.Empty,
            BitmapSizeOptions.FromWidthAndHeight(16, 16));
        return imageSource;
    }

    /// <inheritdoc />
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
}

最后,这是我们用来突出显示验证错误的实际样式,以防万一我在简化时出错。

<Style x:Key="ErrorDisplay" TargetType="FrameworkElement">
    <Setter Property="Margin" Value="5,5,5,5" />
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel LastChildFill="true">
                    <AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" >
                        <Border BorderBrush="red" BorderThickness="1" />
                    </AdornedElementPlaceholder>
                    <Image Source="{Binding Source={x:Static draw:SystemIcons.Error}, Converter={StaticResource IconToImageSourceConverter}, Mode=OneWay}" 
                           Margin="-10,-8,0,0" Height="16" Width="16" VerticalAlignment="Top"
                           ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}"/>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="True">
            <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}" />
        </Trigger>
    </Style.Triggers>
</Style>

0 个答案:

没有答案