[WPF] ContentControl dyn.> Style>DataTemplate...problème Binding

Jayme65 Messages postés 60 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019 - 8 sept. 2016 à 17:42
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 - 11 sept. 2016 à 17:51
Bonjour,

Je dois créer des ContentControl de façon dynamique, pouvoir changer leur contenu et changer leur DataTemplate selon le type de donnée (texte ou image).

(Je crée donc par le code un ContentControl, lui attribue - toujours par le code - un style présent dans le XAML. Dans ce style, j'ai une affectation vers un DataTemplate)

Je suis bloqué par un problème de binding! L'objet s'affiche bien mais je n'arrive pas à accéder à sa propriété 'display_text' dans l'exemple ci-joint!

Merci pour votre aide!
<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525" Background="#FF3A3A48">
    <Window.Resources>
        <local:RelativeToAbsolutePathConverter x:Key="relToAbsPathConverter" />
        <DataTemplate x:Key="ccTexte">
            <TextBlock Text="{Binding display_text}" HorizontalAlignment="Center" Foreground="Beige"/>
            <!--<TextBlock Text="{Binding Path=display_text}" HorizontalAlignment="Center" Foreground="Beige"/>-->
            <!--<TextBlock DataContext="{Binding DataContext,RelativeSource={RelativeSource AncestorType={x:Type ContentControl}}}" Text="{Binding Path=display_text}" HorizontalAlignment="Center" Foreground="Beige"/>-->
        </DataTemplate>
        <DataTemplate x:Key="ccImage">
            <Image x:Name="img" Source="{Binding display_image, Converter={StaticResource relToAbsPathConverter}}"/>
        </DataTemplate>
        <Style x:Name="ccStyle" TargetType="ContentControl">
            <Setter Property="ContentTemplate" Value="{StaticResource ccTexte}"/>
            <!--<Setter Property="ContentTemplate" Value="{StaticResource ccImage}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Source={StaticResource display_image}}" Value="{x:Null}">
                    <Setter Property="ContentTemplate" Value="{StaticResource ccTexte}"/>
                </DataTrigger>
            </Style.Triggers>-->
        </Style>       
    </Window.Resources>
    <Grid Name="mainGrid">
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="416,12,0,0" Name="Button1" VerticalAlignment="Top" Width="75" />
    </Grid>
</Window>

Imports System.IO
Class MainWindow
    Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        mainGrid.Children.Add(designCC(300, 200, "01"))
 
        Dim cc As ContentControl = LogicalTreeHelper.FindLogicalNode(mainGrid, "CC_01")
        cc.Content = New person With {.display_image = "01.png", .display_text = "Text 01"}
    End Sub
 
    Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
        Dim cc As ContentControl = LogicalTreeHelper.FindLogicalNode(mainGrid, "CC_01")
        cc.Content = New person With {.display_image = "02.png", .display_text = "Text 02"}
    End Sub
 
    Private Function designCC(width As Integer, height As Integer, id As String) As ContentControl
        Dim cc As New ContentControl
        cc.Width = width
        cc.Height = height
        cc.Name = "CC_" & id
        cc.Style = DirectCast(Me.Resources("ccStyle"), Style)
        Return cc
    End Function
End Class
 
Public Class person
    Private _display_image As String
    Public Property display_image() As String
        Get
            Return _display_image
        End Get
        Set(value As String)
            _display_image = value
        End Set
    End Property
    Private _display_text As String
    Public Property display_text() As String
        Get
            Return _display_text
        End Get
        Set(value As String)
            _display_text = value
        End Set
    End Property
End Class
 
Public Class RelativeToAbsolutePathConverter
    Implements IValueConverter
    Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.Convert
        Dim relative As [String] = TryCast(value, String)
        If relative Is Nothing Or relative = "" Then
            Return Nothing
        End If
        Return System.AppDomain.CurrentDomain.BaseDirectory & "Images\" & relative
    End Function
    Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function
End Class

2 réponses

Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
9 sept. 2016 à 19:06
Bonsoir

on ne peux pas tester ton code, il manque RelativeToAbsolutePathConverter


Mais si je comprends cette question et la précédente.
Ce que j'aurais fait:
  • Ecrire un Template ou le texte et l'image sont l'un sur l'autre.
  • Binder le texte sur la propriété qui va bien et l'image sur l'autre (à voir s'il faut une image par défaut quand il n'y en a pas)
  • Dans la classe créé une propriété de type Visibility en lecture seule qui retourne si le texte est affiché (Visible, Hidden ou Collapsed), et une autre pour le texte.
  • Dans le template, binder ces propriétés sur les propriétés Visibility de l'image.
  • En plaçant l'image sur le texte, tu n'auras probablement qu'à gérer la visibilité de celle-ci.

0
Jayme65 Messages postés 60 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019 2
Modifié par Jayme65 le 9/09/2016 à 19:10
Regarde bien...tout est là, même 'RelativeToAbsolutePathConverter' ;-)
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
9 sept. 2016 à 20:37
Ha oui tiens, pourtant vs ne veut pas me le trouver...
Je tache d'y retourner dans la soirée
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
11 sept. 2016 à 10:38
Dois moi, par hasard, ça ne serait pas du C# passé par un traducteur?

Parce que chez moi, ça merde au niveau du namespace, qui n'est pas utilisé en VB.Net, mais présent dans ton xaml....

Si c'est le cas, je préférerais voir le code original.
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
11 sept. 2016 à 10:48
A savoir que retraduit en C#, ça ne vaut pas non plus....
0
Jayme65 Messages postés 60 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019 2 > Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024
11 sept. 2016 à 13:29
Non non, c'est du VB d'origine...'WpfApplication1' est d'ailleurs le nom par défaut quand on crée un nouveau projet VB/WPF
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656 > Jayme65 Messages postés 60 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019
11 sept. 2016 à 17:51
oui WpfApplication1 est le nom du projet par défaut et par extension celui du Namespace, mais le Namespace sauf à le mettre intentionnellement n'apparait pas dans VB.Net (en tout cas ni avec 2010, 2012 et 2013)
0
Rejoignez-nous