首页 文章

WPF Generic DataGrid CellTemplate - 绑定到单元格值?

提问于
浏览
4

我在理解WPF中数据绑定的基础知识时遇到了问题 . 我有一个通用的DataGrid(设置了AutoGenerateColumns),它绑定到DataTable,列名在每次加载时都有所不同 . 当dataTable包含boolean类型的列时,我想渲染一个包含表示true和false的自定义图像的列 .

为了实现这一点,我在页面上为celltemplate声明了一个StaticResource,我有c#代码来捕获AutoGenerateColumn事件并使用这个模板:

<DataTemplate x:Key="CheckmarkColumnTemplate">
    <Image x:Name="CheckmarkImage" Source="..\..\images\check.png" Height="16" Width="16" />
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value}" Value="False">
            <Setter TargetName="CheckmarkImage" Property="Source" Value="..\..\images\nocheck.png" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

C#代码:

private void dgData_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    if (e.PropertyType == typeof(bool))
    {
        DataGridTemplateColumn col = new DataGridTemplateColumn();
        Binding binding = new Binding(e.PropertyName);
        col.CellTemplate = (this.Resources["CheckmarkColumnTemplate"] as DataTemplate);
        col.Header = e.PropertyName;
        e.Column = col;
    }
}

这主要是有效的,除了我已经搞砸了DataTrigger Binding属性 . 它永远不会检测列的值何时为“false”,因此它永远不会显示nocheck.png图像 . 我不知道如何编写Binding属性以便引用列的数据绑定值(请记住,列名每次都不同,所以我不能在绑定的Path部分硬编码列名) .

任何人都可以告诉我Binding属性应该是什么样的,以便它只是 grab 列的值?

2 回答

  • 1

    我遇到了同样的问题,仍在寻找答案 . 我目前的解决方案是在 AutoGeneratingColumn 事件处理程序中创建 DataTemplate ,以便 DataTemplate 知道属性名称 .

    private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        e.Column = new DataGridTemplateColumn
        {
            Header = e.PropertyName,
            CellTemplate = CreateSimpleCellTemplate(e.PropertyName)
        }
    }
    
    private static DataTemplate CreateSimpleCellTemplate(string propertyName)
    {
        DataTemplate template = new DataTemplate();
        template.VisualTree = new FrameworkElementFactory(typeof(Label));
        template.VisualTree.SetBinding(ContentProperty, new Binding(propertyName));
        return template;
    }
    
  • 2

    我通过使用不同的方法实现了我所追求的结果 . 我没有使用DataGridTemplateColumn,而是使用DataGridCheckBoxColumn并根据WPF Toolkit的“动手实验室”中使用的样本样式设置自定义ElementStyle:

    <Style x:Key="NoBorderCheckBoxStyle" TargetType="{x:Type CheckBox}">
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Background" Value="{StaticResource CheckBoxFillNormal}"/>
        <Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="FocusVisualStyle" Value="{StaticResource EmptyCheckBoxFocusVisual}"/>
        <Setter Property="HorizontalAlignment" Value="Center"/>
        <Setter Property="IsEnabled" Value="false"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CheckBox}">
                    <BulletDecorator SnapsToDevicePixels="true" Background="Transparent">
                        <BulletDecorator.Bullet>
                            <Canvas x:Name="canvas"  Width="16" Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5">
                                <Image x:Name="checkImage" Source="..\..\images\check.png" Height="16" Width="16"></Image>
                            </Canvas>
                        </BulletDecorator.Bullet>
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/>
                    </BulletDecorator>
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasContent" Value="True">
                            <Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
                            <Setter Property="Padding" Value="4,0,0,0"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                        <Trigger Property="IsChecked" Value="False">
                            <Setter Property="Source" TargetName="checkImage" Value="..\..\images\nocheck.png" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    我从实际的DataGrid列设置(其属性是“IsReadOnly”)读取“IsEnabled”属性时遇到问题,但由于我对DataGrid的使用是只读的,所以我在这里将其设置为false .

相关问题