WPF - Allier image Bitmap a template

soussous Messages postés 10 Date d'inscription samedi 23 août 2008 Statut Membre Dernière intervention 29 mars 2015 - 28 mars 2015 à 10:08
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 - 29 mars 2015 à 17:31
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.
A voir également:

4 réponses

Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
28 mars 2015 à 12:43
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?
0
soussous Messages postés 10 Date d'inscription samedi 23 août 2008 Statut Membre Dernière intervention 29 mars 2015
28 mars 2015 à 13:51
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é :/
0
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
Modifié par Whismeril le 28/03/2015 à 14:46
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
0
soussous Messages postés 10 Date d'inscription samedi 23 août 2008 Statut Membre Dernière intervention 29 mars 2015
28 mars 2015 à 15:28
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).
0
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656
28 mars 2015 à 17:13
Donc en gros ce que tu me dis, WPF est prévu pour les projets statiques.
non pas du tout dans mon exemple le xalm ne sait pas d'avance combien je lui envoie de mois, combien de semaines par moi, combien de jours par semaines.

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).
un template est une ressource. Tu peux créer un dictionnaire de ressource que tu appelles d'ou tu veux. (Je ne l'ai pas encore fait)

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.
je ne comprends pas ce que tu veux dire

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).
comme je l'ai dit plus je ne maitrise pas encore mais sur la base de lecture de tutos, du livre cité plus haut et de mes collègues, je peux affirmer qu'au contraire tu peux faire beaucoup plus de choses dynamiquement.
0
soussous Messages postés 10 Date d'inscription samedi 23 août 2008 Statut Membre Dernière intervention 29 mars 2015
28 mars 2015 à 23:51
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.
0
Whismeril Messages postés 19027 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 24 avril 2024 656 > soussous Messages postés 10 Date d'inscription samedi 23 août 2008 Statut Membre Dernière intervention 29 mars 2015
29 mars 2015 à 09:13
Ok ben là je ne sais pas.
0
soussous Messages postés 10 Date d'inscription samedi 23 août 2008 Statut Membre Dernière intervention 29 mars 2015
29 mars 2015 à 11:07
Bon, tant pis pour moi.
Merci beaucoup déjà pour toutes ces infos.
0
soussous Messages postés 10 Date d'inscription samedi 23 août 2008 Statut Membre Dernière intervention 29 mars 2015
29 mars 2015 à 14:28
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...)
0
Rejoignez-nous