【问题标题】:Apply Datatemplate for Datagrid autogenerated columns - Dynamic binding of Column Name为 Datagrid 自动生成的列应用数据模板 - 列名的动态绑定
【发布时间】:2019-08-27 02:42:27
【问题描述】:

我使用了自动生成的Datagrid列的Datatemplate设置为true,我想动态绑定Datatemplate中的列名,这样我就可以为所有列使用一个Datatemplate,可以吗??

我已尝试使用 DataGridTemplateColumn 和 DataTemplate,但看起来我必须为每个列创建 DataGridTemplateColumn,因此请继续使用 DataTemplate。

使用 DataTemplate 的目的是根据列值显示图像。

XAML:

<Image Name="theImage" Width="40" Height="30" Source="../Resources/Help.png"/>
   <DataTemplate.Triggers>
    <DataTrigger Binding="{Binding Path=Col1}" Value="0,00">
       <Setter TargetName="theImage" Property="Source" Value="../Resources/pmIcons/minus-256.png"/>
    <DataTrigger Binding="{Binding Path=Col1}" Value="1,00">
        <Setter TargetName="theImage" Property="Source" Value="../Resources/pmIcons/greenRoundTick.png"/>
    </DataTrigger>
     <DataTrigger Binding="{Binding Path=Col1}" Value="2,00">
         <Setter TargetName="theImage" Property="Source" Value="../Resources/pmIcons/redCross.png"/>
     </DataTrigger>     
   </DataTemplate.Triggers>
 </DataTemplate>


<DataTemplate>
<Image Name="theImage" Width="40" Height="30" Source="../Resources/Help.png"/>
   <DataTemplate.Triggers>
    <DataTrigger Binding="{Binding Path=Col2}" Value="0,00">
       <Setter TargetName="theImage" Property="Source" Value="../Resources/pmIcons/minus-256.png"/>
    <DataTrigger Binding="{Binding Path=Col2}" Value="1,00">
        <Setter TargetName="theImage" Property="Source" Value="../Resources/pmIcons/greenRoundTick.png"/>
    </DataTrigger>
     <DataTrigger Binding="{Binding Path=Col2}" Value="2,00">
         <Setter TargetName="theImage" Property="Source" Value="../Resources/pmIcons/redCross.png"/>
     </DataTrigger>   
   </DataTemplate.Triggers>
 </DataTemplate>

Pm.xaml.vb:

Private Sub AutoGeneratingColumn(sender As Object, e As DataGridAutoGeneratingColumnEventArgs)


        If e.PropertyName = "IsReadable" Or e.PropertyName = "HasValue" Then
            e.Cancel = True
            Exit Sub
        End If


      Dim oGrdTemplate As DataGridTemplateColumn = New DataGridTemplateColumn
        oGrdTemplate.Header = e.Column.Header               
        oGrdTemplate.CellTemplate = CType(grdTotal.FindResource("test"), DataTemplate)
        e.Column = oGrdTemplate

预期:上面的代码有效,但我有 40 列,所以我必须将相同的 DataTemplate 复制 40 次。我觉得这不是更好的方法。我想在每个列中将相应的列名绑定为 Col1、Col2、Col3 等。如果不是在代码隐藏中,它有没有办法在 Xaml 中很好地绑定?

我尝试使用&lt;DataTrigger Binding="{Binding Path=.}" Value="0,00"&gt; 不起作用。

【问题讨论】:

    标签: wpf vb.net data-binding datagrid


    【解决方案1】:

    您的设计还有很大的改进空间,例如,您应该使用Enumeration 作为列,而不是 40 个不同的命名对象。

    但即使使用您当前的设计,您也可以实现一个 IValueConverter 直接将值转换为正确的图像 URI,然后您可以通过转换器将 Image 直接绑定到您的源值。

    在我的脑海中,未经测试:

    写一个转换器:

    <ValueConversion(GetType(Double), GetType(String))>
    Public Class MyValueToImageConverter
        Implements IValueConverter
    
        Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
            Try
                If CDbl(value) = 0.0 Then Return "../Resources/pmIcons/minus-256.png"
                If CDbl(value) = 1.0 Then Return "../Resources/pmIcons/greenRoundTick.png"
                If CDbl(value) = 2.0 Then Return "../Resources/pmIcons/redCross.png"
            Catch ex As Exception
                'this is okay for our purpose
            End Try
            Return "../Resources/Help.png"
        End Function
    
        Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
            Throw New NotImplementedException()
        End Function
    End Class
    

    嵌入到您的资源中(WindowPage 等)

    <Window.Resources>
        <local:MyValueToImageConverter x:Key="myConverter"/>
    </Window.Resources>
    

    并像这样绑定你的列:

    <Image Source="{Binding Col1,Converter={StaticResource myConverter}}" />
    

    然后,您可以使用不祥的“标签”DependencyProperty 将此功能包装到 UserControl

    <UserControl
        x:Class="StatusIcon"
        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:local="clr-namespace:WpfApp1"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        d:DesignHeight="450"
        d:DesignWidth="800"
        mc:Ignorable="d"
        >
        <UserControl.Resources>
            <local:MyValueToImageSourceConverter x:Key="_conv" />
        </UserControl.Resources>
        <Image Source="{Binding Tag, RelativeSource={RelativeSource AncestorType={x:Type local:StatusIcon}}, Converter={StaticResource _conv}}" />
    </UserControl>
    

    最后得到像这样整洁干净的东西:

    <local:StatusIcon Tag="{Binding Col1}"/>
    

    然后您可以通过将 Tag 替换为您自己的 DependencyProperty 称为 Value 或类似的东西来进一步改进这一点

    【讨论】:

      【解决方案2】:

      那时我已经参考了@themightylc 的答案 我添加了 cls_PMImageConverter 类, <local:cls_PMImageConverter x:Key="PMImageConverter"/>, <DataTemplate x:Key="colTemplate_Col1"> <Image Source="{Binding Path=Col1, Converter={StaticResource PMImageConverter}}" /> </DataTemplate> <DataTemplate x:Key="colTemplate_Col2"> <Image Source="{Binding Path=Col2, Converter={StaticResource PMImageConverter}}" /> </DataTemplate>

      等到 col40

      并在 AutogeneratedColumn 事件中将此模板称为

      Dim oGrdTemplate As DataGridTemplateColumn = New DataGridTemplateColumn
       oGrdTemplate.Header = e.Column.Header
       oGrdTemplate.CellTemplate = CType(grdTotal.FindResource("colTemplate_"+e.PropertyName), DataTemplate)
       e.Column = oGrdTemplate `
      

      它有效.. 但是,它仍然不是动态仪式吗?我可以进一步改进这段代码吗??

      【讨论】:

      • 如果您可以将模板直接绑定到列的 DataContext 属性的名称(col1-coln)将不再重要,然后您将实现我认为您所追求的(一个仅模板)。但正如我想说的:据我所知,您的问题的真正根源在于模型设计 - 而不是视图。
      • 我的想法是在视图中显示带有自动生成的列和行的数据网格,并具有基于值的可编辑、可更新、只读等功能。有时数据网格中的列数也可以更改,以便它重新创建列标题,即 Me.DataContext = Nothing ' Me.DataContext = prv_clspm。在这种情况下我如何使用枚举。还有一个问题,stackoverflow.com/questions/55536183/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      • 2023-03-22
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      相关资源
      最近更新 更多