web-dev-qa-db-fra.com

WPF - Comment lier un DataGridTemplateColumn

J'essaie d'obtenir le nom de la propriété associée à un DataGridColumn particulier, afin que je puisse ensuite faire des choses en fonction de cela. Cette fonction est appelée lorsque l'utilisateur clique sur l'élément de menu contextuel dans l'en-tête de la colonne ...

C'est très bien pour les types de colonnes prêtes à l'emploi comme DataGridTextColumn, car ils sont liés, mais le problème est que certaines de mes colonnes sont DataGridTemplateColumns, qui ne sont pas lié.

private void GroupByField_Click (object sender, RoutedEventArgs e){
        MenuItem mi = (MenuItem)sender;
        ContextMenu cm = (ContextMenu) mi.Parent;
        DataGridColumnHeader dgch = (DataGridColumnHeader) cm.PlacementTarget;  
        DataGridBoundColumn dgbc = (DataGridBoundColumn) dgch.Column;
        Binding binding = (Binding) dgbc.Binding;
        string BoundPropName = binding.Path.Path;

        //Do stuff based on bound property name here...
    }

Donc, prenez par exemple ma colonne Name ... c'est une DataGridTemplateColumn (car elle contient une image et d'autres éléments). Par conséquent, il n'est pas réellement lié à la propriété 'Name' ... mais j'aimerais l'être, pour que le code ci-dessus fonctionne.

Ma question est en deux parties, vraiment:

  1. Est-il possible de rendre un DataGridTemplateColumn lié, pour que le code ci-dessus fonctionne? Puis-je le lier d'une manière ou d'une autre à une propriété?

  2. Ou ai-je besoin de quelque chose de complètement différent et de changer le code ci-dessus?

Merci d'avance!

AT

19
Andy T

Bien que vous ne puissiez pas lier une colonne de modèle, vous pouvez lier l'un des contrôles contenus dans cette colonne. Voici comment j'ai résolu un problème similaire:

<DataGridTemplateColumn Header="ColumnHeader">
     <DataGridTemplateColumn.CellTemplate>
           <DataTemplate>
                 <local:CustomisedUIElement Text="{Binding Path=PropertyToBindTo}"/>
           </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Si j'ai bien compris l'exemple initial, cela signifierait changer la logique de la méthode GroupByField_Click() pour vérifier si la colonne d'envoi était une colonne de modèle, puis regarder les éléments qu'elle contenait pour obtenir l'objet Binding.

32
rankAmateur

Pour moi, ClipboardContentBinding de DataGridTemplateColumn est une solution:

Private Function FindBoundProperty(ByVal col As DataGridColumn) As String

    Dim boundColumn As DataGridBoundColumn = TryCast(col, DataGridBoundColumn)
    Dim boundPropertyName As String = ""
    Dim binding As Binding
    If col.DependencyObjectType.Name = "DataGridTextColumn" Then
        binding = TryCast(boundColumn.Binding, Binding)
        boundPropertyName = binding.Path.Path
    End If
    If col.DependencyObjectType.Name = "DataGridTemplateColumn" Then
        binding = TryCast(col.ClipboardContentBinding, Binding)
        boundPropertyName = binding.Path.Path
    End If
    Return boundPropertyName

End Function
3
slavica

C'est délicat. Nous avons atteint la liaison en traversant vers son grand-parent UserControl (nous avions DataGrid dans un UserControl) et UserControl était lié à un présentateur (modèle dans notre cas). Dans le code ci-dessous, vérifiez la propriété SelectedItem de AutoCompleteBox placée à l'intérieur de DataGridTemplateColumn.

<wpfToolkit:DataGridTemplateColumn  Header="{x:Static resources:Store.ItemNameC}" Width="0.60*">
  <wpfToolkit:DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <extended:HOAutoCompleteBox
                            IsTextCompletionEnabled ="True"
                            x:Name="ItemAutoCompleteBox"
                            Populating="ItemAutoCompleteBox_Populating"
                            DefaultType="HealthObject.ObjectModel.pSearchStockItemResult,HealthObject.ObjectModel"
                            Text="{Binding Path= ItemName, Mode=TwoWay}" 
                            <!--- **** HERE IS THE BINDING SAMPLE *****-->
            SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},  Path=Model.SelectedStockItem, Mode=TwoWay}">
        </extended:HOAutoCompleteBox>
    </DataTemplate>
  </wpfToolkit:DataGridTemplateColumn.CellEditingTemplate>

</wpfToolkit:DataGridTemplateColumn>
2
Gopinath

Vous pouvez utiliser dgbc.ClipboardContentBinding;

1
Orlangoor
  1. Non, car DataGridTemplateColumn n'hérite pas de DataGridBoundColumn, donc le transtypage en DataGridBoundColumn échouerait.
    Pour faire fonctionner le code ci-dessus, toutes vos colonnes doivent hériter de la classe abstraite DataGridBoundColumn. La création de classes de colonnes dérivées personnalisées au lieu de DataGridTemplateColumn devrait donc fonctionner.

  2. Vous pouvez simplement remplir un

    Dictionary<DataGridColumn, string> BoundPropName;

    à l'initialisation, puis faites

    var propName = BoundPropName[dgch.Column]

0
majocha