Применить Datatemplate для автоматически сгенерированных столбцов Datagrid - динамическое связывание имени столбца - PullRequest
1 голос
/ 05 апреля 2019

Я использовал Datatemplate для столбцов Datagrid, для которого автоматически сгенерировано значение 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 хорошо и хорошо, если не в code-behind возможно?

Я пытался с <DataTrigger Binding="{Binding Path=.}" Value="0,00"> не работает.

Ответы [ 2 ]

0 голосов
/ 05 апреля 2019

Я передал ответ @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 `

Это работает .. Но все же, это не динамический обряд?Могу ли я улучшить этот код дальше ??

0 голосов
/ 05 апреля 2019

Существует много возможностей для улучшения вашего дизайна, например, вы должны иметь 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

Вставить в ваши ресурсы (Window или Page и т. Д.)

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

И связывайте свои столбцы так:

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

Затем вы можете обернуть эту функцию в UserControl, используя зловещий «тег» DependencyProperty

<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 или чем-то похожим

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...