WPF - Allier image Bitmap a template

Signaler
Messages postés
11
Date d'inscription
samedi 23 août 2008
Statut
Membre
Dernière intervention
29 mars 2015
-
Messages postés
14617
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 août 2020
-
Bonjour,

J'ai créé un Template pour créer un bouton avec les coins arrondis :

string template = "<ControlTemplate  xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' TargetType=\"Button\">";
template += "<Border CornerRadius=\"20\" BorderThickness=\"1\" BorderBrush=\"Black\">";
template += "<ContentPresenter/>";
template += "</Border>";
template += "</ControlTemplate>";


Je l'envoi au bouton via

b.Template=(ControlTemplate)XamlReader.Parse(template);
par contre j'aimerai lui affecter un System.Drawing.Bitmap que le programme génère.

Je suis maintenant bloqué car le Template existant, je ne peux pas ajouter une image.

Je n'ai pas réussi a trouver comment mettre des coins arrondis via le code, ni a ajouter mettre mon bitmap via Template. La seule solution que j'ai trouvé est de créer un dossier temporaire, enregistrer mes images a l'intérieur et les importer via le template

string template = "<ControlTemplate  xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' TargetType=\"Button\">";
template += "<Border CornerRadius=\"20\" BorderThickness=\"1\" BorderBrush=\"Black\">";
template += "<Border.Background>";
template += "<ImageBrush ImageSource=\"dossierTemp\\"+nomFichierTemp+".png\" />";
template += "</Border.Background>";
template += "<ContentPresenter/>";
template += "</Border>";
template += "</ControlTemplate>";


Auriez vous une manière d'allier les 2 actions autre que via l'écriture sur disque?

Merci.

4 réponses

Messages postés
14617
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 août 2020
427
Bonjour, je n'ai que quelques notions de wpf, alors bon ma question va peut-être être bête.

Pourquoi écris tu un template dans le code csharp et par directement de le xaml?
Messages postés
11
Date d'inscription
samedi 23 août 2008
Statut
Membre
Dernière intervention
29 mars 2015

Je suis au tout début de XAML, je ne connais pas tout, il y a surement de meilleures méthodes. Ce Template est utilisé sur toutes mes pages et mes objets sont a 50% créés dynamiquement.
Je ne sais pas comment faire un template et le balancer a n'importe quel objet du projet.
Je sors de 8 ans sur winform et je suis bien largué :/
Messages postés
14617
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 août 2020
427
OK, le but de wpf, c'est de faire du code "métier" d'un coté et de l'IHM dans le xaml, pas vraiment de mélanger les 2.
As tu téléchargé des sources exemples, on en a quelques une.
Je te conseille aussi le livre WPF par la pratique.



Par exemple, pour un projet récent (mon premier en WPF c'est surement améliorable!) j'affiche un calendrier annuel complet.
Dans le code csharp,
  • je génère une liste de mois,
  • chaque moi a un nom et contient une liste de semaines,
  • chaque semaine a un numéro et contient une lite de jours,
  • chaque jour a un nom, un numéro, une description et une couleur.


Voila le xalm (WindowsMain.xaml), avec chqaue template

    <Window.Resources>
        <DataTemplate x:Key="styleJour">
            <StackPanel Background="Gray" Height="Auto" HorizontalAlignment="Left" Name="grdJournee" VerticalAlignment="Top" Width="Auto" Orientation="Horizontal" Margin="0,1" >
                <TextBox Width="9" Height="16" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="7" x:Name="jourDeLaSemaine" Text="{Binding Mode=OneWay, Path=JourString}" BorderThickness="0" Background="{Binding Couleur}" Focusable="False" />
                <TextBox Width="12" Height="16" HorizontalAlignment="Left"  VerticalAlignment="Center" FontSize="7" x:Name="jourDuMoi" Text="{Binding JourDansMoi, Mode=OneWay}" BorderThickness="0" Background="{Binding Couleur}" Focusable="False" />
                <TextBox Width="53" Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="7" x:Name="descriptionJour" Text="{Binding Description}" HorizontalContentAlignment="Center" BorderThickness="0"  Background="{Binding Couleur}" Focusable="False" />
            </StackPanel>
        </DataTemplate>

        <DataTemplate x:Key="styleSemaine">
            <Grid Background="Pink" Height="Auto" HorizontalAlignment="Center" Name="grdSemaine" VerticalAlignment="Center" Width="Auto" Margin="1,1,1,1">
                <TextBlock Name="txtNumSemaine" VerticalAlignment="Center" Text="{Binding Path=NumeroAffiche}" HorizontalAlignment="Left" FontSize="8" Background="Red">
                    <TextBlock.RenderTransform>
                        <TransformGroup>
                            <RotateTransform CenterX="{Binding Path=CenterX}" CenterY="{Binding Path=CenterY}" Angle="90"/>
                        </TransformGroup>
                    </TextBlock.RenderTransform>
                </TextBlock>
                <ListBox Height="Auto" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" ItemTemplate="{StaticResource styleJour}" ItemsSource="{Binding Path=.Journees}"  HorizontalAlignment="Left" Margin="17,0,0,0" x:Name="lstJours" VerticalAlignment="Top" Width="Auto"></ListBox>
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="styleMoi">
            <Grid Background="Azure" Height="Auto" Width="Auto">
                <TextBox Height="17" Width="100" Text="{Binding Nom}" VerticalAlignment="Top" Name="txMoi" BorderThickness="0" HorizontalContentAlignment="Center" FontSize="13" />
                <ListBox Height="Auto" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" ItemTemplate="{StaticResource styleSemaine}"  ItemsSource="{Binding Path=.Semaines}" HorizontalAlignment="Left" Margin="0,17,0,0" Name="lstMoi" VerticalAlignment="Top" Width="Auto" BorderThickness="0"></ListBox>
            </Grid>

        </DataTemplate>
    </Window.Resources>

    <Grid>
            <ListBox Height="615" Width="1263" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" ItemTemplate="{StaticResource styleMoi}"  ItemsSource="{Binding}" HorizontalAlignment="Left" Name="lstCalendrier" VerticalAlignment="Top" VerticalContentAlignment="Top" Margin="0,40,0,0" Background="LightYellow">
                    <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" Margin="0"></StackPanel>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.RenderTransform>
                    <!--Zoom Bindé sur le slider-->
                    <TransformGroup>
                        <ScaleTransform>
                            <ScaleTransform.ScaleX>
                                <Binding ElementName="sldZoom" Path="Value" Mode="OneWay"/>
                            </ScaleTransform.ScaleX>
                            <ScaleTransform.ScaleY>
                                <Binding ElementName="sldZoom" Path="Value" Mode="OneWay"/>
                            </ScaleTransform.ScaleY>
                        </ScaleTransform>
                        </TransformGroup>
                </ListBox.RenderTransform>
            </ListBox>
        <Slider Height="25" HorizontalAlignment="Left" Margin="12,0,0,0" Name="sldZoom" VerticalAlignment="Top" Width="235" Maximum="1.5" Value="1" Minimum="0.5" LargeChange="0.05"/>
    </Grid>
</Window>


Modérer m'amène à intervenir dans de nombreux posts, mais les seuls langages que je connaisses sont le C# et un peu de VB. Pour vos codes pensez à la coloration.
Réponse trouvée ->Question Résolue
Messages postés
11
Date d'inscription
samedi 23 août 2008
Statut
Membre
Dernière intervention
29 mars 2015

Donc en gros ce que tu me dis, WPF est prévu pour les projets statiques.
Moi qui ne sais pas ce que va devoir afficher le logiciel car le nombre d'éléments, les images sont calculés dynamiquement. WPF est incapable de le gérer?
Les Templates ont étés créés sur WindowsMain.xaml, mais ne seront (pour moi) pas utilisable dans tous les xaml du logiciel (j'en suis a 9 tout en étant au début du dev).
Je l'ai mis comme ci dessus mon Template, mais il est dans une méthode statique (donc utilisable dans l'état par tout le logiciel).
Ce template est utilisé dans 7 de ces pages et devra l'être dans au moins 15 autres arrivantes. C'est la méthode que j'ai trouvé pour si en cas de modification, celle ci soit effectives dans toutes mes pages, sans recopie du code.

Mon problème principal vient du fait que j'ai des photos utilisateurs qui peuvent être modifiées. La photo s'affiche, on peut rechercher une nouvelle photo, mais lorsque je veux l'enregistrer, celle-ci étant accrochée au logiciel, j'ai un refus d'écriture. Donc je dois tout d'abord charger ce fichier en ram et l'afficher depuis cet emplacement. Et là je ne vois pas comment, je peux utiliser les template qui me donne la forme de mes controls et charger une image qui est en RAM.

Venant du Winform, je suis frustré par le fait que l'on puisse pas tout faire en WPF par le code et se servir du XAML pour ce qui reste statique (faudra s'y habituer et trouver des parades).
Messages postés
11
Date d'inscription
samedi 23 août 2008
Statut
Membre
Dernière intervention
29 mars 2015

Merci pour l'info du dictionnaire de ressource, je vais potasser vers ce sens.
Pour ce dont tu ne comprends pas, je cherche tout simplement a mettre une image en background d'un control sans pour autant que le fichier que j'utilise soit utilisé par le logiciel.
Dans le système que j'ai mis en place, on a cette ligne :
template += "<ImageBrush ImageSource=\"" + img + "\" />";

cette ligne va mettre une image en fond du control. Par contre, il va lier le fichier au control, ce qui bloque le fichier. Voulant tout simplement changer dynamiquement le fichier, j'ai un blocage car le fichier est en cours d'utilisation.
Chose simple a tester, pour voir ce que ca donne, ouvrir un projet avec une/des image(s), pendant que le logiciel tourne, ouvrir une des images avec paint et simplement sauvegarder. Le fichier étant en cours d'utilisation, il ne peut être modifié. Pour parer ce soucis, la seule chose que j'ai trouvé est de copier toutes les images que j'utilise dans un dossier temporaire avec un identifiant unique et de recharger ces images dès qu'elles sont modifiées. Mais je trouve ca vraiment pas terrible. Que si je trouvais une manière d'affecter un System.Drawing.Bitmap en tant que ImageSource, cela réglerai mon problème.
Messages postés
14617
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 août 2020
427 >
Messages postés
11
Date d'inscription
samedi 23 août 2008
Statut
Membre
Dernière intervention
29 mars 2015

Ok ben là je ne sais pas.
Messages postés
11
Date d'inscription
samedi 23 août 2008
Statut
Membre
Dernière intervention
29 mars 2015

Bon, tant pis pour moi.
Merci beaucoup déjà pour toutes ces infos.
Messages postés
11
Date d'inscription
samedi 23 août 2008
Statut
Membre
Dernière intervention
29 mars 2015

Voila, j'ai ajouté dans <Application.Resources> le Template suivant :
<ControlTemplate x:Key="T_Boutons" TargetType="Button">
            <Border CornerRadius="20" BorderThickness="1" BorderBrush="Black">
                <ContentPresenter/>
                <Border.Background>
                    <ImageBrush Stretch="Uniform" TileMode="None" ImageSource="{Binding Photo}" />
                </Border.Background>
            </Border>
        </ControlTemplate>

J'ai testé sur un bouton du projet qui n'est pas généré (on commence doucement)
<Button Template="{StaticResource T_Boutons}"  Height="100" HorizontalAlignment="Left" Margin="10,10,0,0" Name="Retour" VerticalAlignment="Top" Width="100" Click="Retour_Click" />


J'ai bien le bouton qui se forme comme je le veux (merci Whismeril).

Par contre, je n'arrive pas a gérer l'image de fond (je ne veux pas que tous mes boutons aient la même image...)
Messages postés
14617
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
14 août 2020
427 >
Messages postés
11
Date d'inscription
samedi 23 août 2008
Statut
Membre
Dernière intervention
29 mars 2015

Y a moyen de préciser quel bouton prend quel template, mais là je n'ai pas d'exemple sous la main, et je ne travaille pas la semaine prochaine.
Mais y'en a sur le net.