IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

Copier un DataGrid dans le presse papier en tant qu'imaeg


Sujet :

Windows Presentation Foundation

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 57
    Points : 66
    Points
    66
    Par défaut Copier un DataGrid dans le presse papier en tant qu'imaeg
    Bonjour,

    j'aimerais, qu'importe l'interaction effectuée par l'utilisateur, pourvoir copier un DataGrid vers le presse papier, pour ensuite le réinjecter dans des rapports Word rapidement.

    Cordialement, Orwel

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Bonjour,

    Qu'est-ce que tu n'arrives pas à faire ?

    Il faut procéder de la manière suivante :

    - Soit utiliser le DataGrid existant soit créer un contrôle qui aura l'aspect de l'image que tu souhaites copier.
    - À partir de cet UIElement, générer une image à l'aide de la méthode Render de la classe RenderTargetBitmap (cf msdn)
    - Enfin, il faut copier le flux (Stream) de l'image obtenu dans le presse papier à l'aide des méthodes de la classe statique Clipboard

    NeoKript

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 57
    Points : 66
    Points
    66
    Par défaut
    Merci beaucoup, ta réponse m'a permit d'avancer.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            public static void PushInClipboard(DataGrid dataGrid)
            {
                var img = new RenderTargetBitmap((int)dataGrid.RenderSize.Width, (int)dataGrid.RenderSize.Height, 96, 96, PixelFormats.Pbgra32);
                img.Render(dataGrid);
                Clipboard.SetImage(img);
            }
    Mais j'ai encore un problème; lorsque le DataGrid a beacuoup d'élément, une Scroll Bar apparaît et seulement la partie visible du DataGrid est convertie en image, avec la Scroll Bar.

    J'ai donc désactivée la Scroll Bar du DataGrid et demandais la réactualisation du DataGrid. La Scroll Bar n'apparaît plus sur l'image, mais le DataGrid apparaît toujours incomplet. Il est comme il apparaît à l'écran.

    Je pense que je dois utiliser les méthodes DataGrid.MEasure et DataGrid.Arrange, mais je ne sais pas quelles paramètres y passer, cardataGrid.Width et dataGrid.Heigth = NAN.

    Mon code actuelle non fonctionnel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
            public static void PushInClipboard(DataGrid dataGrid)
            {
                dataGrid.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
                dataGrid.UpdateLayout();
                dataGrid.Measure(new Size(dataGrid.Width, dataGrid.Height));
                dataGrid.Arrange(new Rect(new Size(dataGrid.Width, dataGrid.Height)));
                var img = new RenderTargetBitmap((int)dataGrid.RenderSize.Width, (int)dataGrid.RenderSize.Height, 96, 96, PixelFormats.Pbgra32);
                img.Render(dataGrid);
                Clipboard.SetImage(img);
            }

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Pour la taille du contrôle, essayes d'utiliser les propriétés DesiredHeight et DesiredWidth, ça devrait fonctionner.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 57
    Points : 66
    Points
    66
    Par défaut
    Effectivement, il s'agit de l'attribut qui connait la taille du DataGrid. Mais celui-ci est limité par la taille du composant parent.

    Donc il faudrait le sortir du composant parent, le copier, et le remettre.
    Ou effectuer une copie.

    Voici un code de test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <Window x:Class="PushDataGridInClipboard.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <DataGrid Name="DataGrid" AutoGenerateColumns="False" MouseDoubleClick="DataGrid_MouseDoubleClick">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Value}"/>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
     
    namespace PushDataGridInClipboard
    {
        /// <summary>
        /// Logique d'interaction pour MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            class MyDouble
            {
                public double Value { get; set; }
                public MyDouble(double value) { Value = value; }
            }
     
            public MainWindow()
            {
                InitializeComponent();
                var list = new List<MyDouble>();
                for (int i = 0; i < 200; i++)
                    list.Add(new MyDouble(i));
                DataGrid.ItemsSource = list;
            }
     
            private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
            {
                PushInClipboard((DataGrid)sender);
            }
     
            /// <summary>
            /// Copie le DataGrid en tant qu'image dans le presse papier.
            /// </summary>
            public static void PushInClipboard(DataGrid dataGrid)
            {
                dataGrid.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
                dataGrid.UpdateLayout();
                dataGrid.Measure(new Size(dataGrid.DesiredSize.Width, dataGrid.DesiredSize.Height));
                dataGrid.Arrange(new Rect(new Size(dataGrid.DesiredSize.Width, dataGrid.DesiredSize.Height)));
                var img = new RenderTargetBitmap((int)dataGrid.DesiredSize.Width, (int)dataGrid.DesiredSize.Height, 96, 96, PixelFormats.Pbgra32);
                img.Render(dataGrid);
                Clipboard.SetImage(img);
            }
        }
    }
    Edit :: DesiredSize n'est pas la taille total du composant.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Instancies un nouveau DataGrid (par code) en ajoutant les mêmes propriétés ItemsSource, Columns ... Comme ça le contrôle ne sera pas lié à ton UI et tu pourras lui donner la taille qu'il désire...

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 57
    Points : 66
    Points
    66
    Par défaut
    Voici le code de la copie :
    var grid = new DataGrid();

    var column = new DataGridTextColumn();
    column.Binding = new Binding("Value");
    grid.Columns.Add(column);
    grid.ItemsSource = dataGrid.ItemsSource;
    Plusieurs problèmes avec ta solution :

    1) Je connais pas la taille qu'il désire. Si il n'est pas attaché à l'UI, alors tout les paramètre de taille sont à 0, or ni Heigth et Width qui sont encore un NAN.

    J'ai essayé de forcer la taille du DataGrid en modifiant Heigth et Width, j’obtiens une image noir.

    2)La copie me semble limité et difficile, car alors il faudrait une méthode de copie vers le presse papier par DataGrid.

    Sauf si il existe une méthode pour copier certaine propriété du DataGrid.

    En essayant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                var grid = new DataGrid();
                foreach (var column in dataGrid.Columns)
                    grid.Columns.Add(column);
                grid.ItemsSource = dataGrid.ItemsSource;
    J'ai la fameuse erreur qu'une colonne ne peut appartenir qu'a un unique DataGrid.

    ---------
    Je pense qu'il serait préférable de sortir le DataGrid et l'ajouter à une fenêtre de taille infinie. Mais je ne sais pas comment faire pour récupérer le conteneur du DataGrid pour le retirer et donner une taille infinie à une fenêtre.

    Sinon, je pense qu'il est illogique de chercher à faire des images aussi grande. Je vais voir si je peux modifier le besoin.

    Merci beaucoup pour ton aide.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 57
    Points : 66
    Points
    66
    Par défaut
    Voici une solution. Elle améliore légèrement l'affichage en modifiant certain attribut du DataGrid et les restaure à l'origine à la fin de son exécution. Seul la partie visible du DataGrid ira dans le presse papier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
            /// <summary>
            /// Copie le DataGrid en tant qu'image dans le presse papier.
            /// </summary>
            public static void PushInClipboard(DataGrid dataGrid)
            {
                //Savegarde les attributs modifiées du DataGrid
                var tmpRenderSize = dataGrid.RenderSize;
                var tmpHorizontal = dataGrid.HorizontalScrollBarVisibility;
                var tmpVertical = dataGrid.VerticalScrollBarVisibility;
                //Modifie les attributs pour un meilleur affichage
                dataGrid.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
                dataGrid.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
                dataGrid.Measure(new Size(dataGrid.DesiredSize.Width, dataGrid.DesiredSize.Height));
                dataGrid.Arrange(new Rect(dataGrid.DesiredSize));
                dataGrid.UpdateLayout();
                //Sauvegarde l'affichage dans le presse papir
                var img = new RenderTargetBitmap((int)dataGrid.RenderSize.Width, (int)dataGrid.RenderSize.Height, 96, 96, PixelFormats.Pbgra32);
                img.Render(dataGrid);
                Clipboard.SetImage(img);
                //Restore les attributs d'origine
                dataGrid.HorizontalScrollBarVisibility = tmpHorizontal;
                dataGrid.VerticalScrollBarVisibility = tmpVertical;
                dataGrid.Measure(new Size(tmpRenderSize.Width, tmpRenderSize.Height));
                dataGrid.Arrange(new Rect(tmpRenderSize));
                dataGrid.UpdateLayout();
            }

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Ça doit être jouable de faire ça, avec la DesiredSize de l'ItemPresenter contenu dans le ScrollViewer du DataGrid.

    Sinon une méthode plus simple (mais moins propre) consiste à récupérer la propriété RowHeight du DataGrid multipliée par le nombre d'item de l'ItemsSource + la taille du Header... Et de définir cette valeur en tant qu'hauteur souhaitée lors du rendu (dans un DataGrid copié).

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 57
    Points : 66
    Points
    66
    Par défaut
    Merci bien, mais je vais arrêter ici sur ce problème. D'autres priorités

    Je ne sais pas si je devrais mettre résolue, car la question n'est pas entièrement résolue. Mais en redéfinissant les besoins des utilisateurs, soit copié le DataGrid vers un document Word au final. Si le DataGrid est trop grand, il ne logera pas dans le document. C'est donc l'utilisateur qui redimensionne le DataGrid pour obtenir l'affichage qu'il désire (les DataGris on la possibilité de masquer les colonnes et sont dans des zones dimensionnables

    Point intéressant, plutôt que perdre du temps à réaliser une chose complexe, chercher à redéfinir le cahier de spec. vers une fonctionnalité moins complexe, mais qui reste ce que l’utilisateur attend

Discussions similaires

  1. [Tkinter] Copier un texte dans le presse-papier
    Par fire.stone dans le forum Tkinter
    Réponses: 3
    Dernier message: 01/05/2018, 10h22
  2. Copier des données dans le presse papier
    Par Orakle dans le forum Access
    Réponses: 11
    Dernier message: 06/12/2005, 14h11
  3. [Système] Comment copier un fichier dans le presse papier ?
    Par le y@m's dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 19/09/2005, 12h03
  4. Réponses: 3
    Dernier message: 06/07/2005, 11h27
  5. Comment copier une image dans le presse papier.
    Par cprogil dans le forum Langage
    Réponses: 7
    Dernier message: 09/09/2003, 15h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo