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

Jayme65 64 Messages postés lundi 23 avril 2007Date d'inscription 15 décembre 2016 Dernière intervention - 8 sept. 2016 à 17:42 - Dernière réponse : Whismeril 11618 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 17 juin 2018 Dernière intervention
- 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
Afficher la suite 

Votre réponse

7 réponses

Whismeril 11618 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 17 juin 2018 Dernière intervention - 9 sept. 2016 à 19:06
0
Merci
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.

Jayme65 64 Messages postés lundi 23 avril 2007Date d'inscription 15 décembre 2016 Dernière intervention - 9 sept. 2016 à 19:10
Regarde bien...tout est là, même 'RelativeToAbsolutePathConverter' ;-)
Whismeril 11618 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 17 juin 2018 Dernière intervention - 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
Commenter la réponse de Whismeril
Whismeril 11618 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 17 juin 2018 Dernière intervention - 11 sept. 2016 à 10:38
0
Merci
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.
Whismeril 11618 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 17 juin 2018 Dernière intervention - 11 sept. 2016 à 10:48
A savoir que retraduit en C#, ça ne vaut pas non plus....
Jayme65 64 Messages postés lundi 23 avril 2007Date d'inscription 15 décembre 2016 Dernière intervention > Whismeril 11618 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 17 juin 2018 Dernière intervention - 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
Whismeril 11618 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 17 juin 2018 Dernière intervention > Jayme65 64 Messages postés lundi 23 avril 2007Date d'inscription 15 décembre 2016 Dernière intervention - 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)
Commenter la réponse de Whismeril

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.