none
Pb format date datagrid

    Question

  • Bonjour,

    Je développe une petite application WPF en C#, qui a pour but d'importer un fichier Excel, dans un datagrid.

    Le Problème qui se pose est que lors de l'importation, je n'arrive pas à retrouver le format date du fichier excel, dans ma datagrid.

    Malgré toutes les recherches effectuées, je ne parviens pas à trouver une solution à mon problème.J'ai essayé de modifier de la sorte :

    <DataGridTextColumn Binding="{Binding StartDate, StringFormat=\{0:dd.MM.yy\}}" />

    mais rien y fait.

    J'ai également essayer de créer une classe "IvalueConverter, mais pas plus de résultat que précédemment. peux-être une problème de conversion du format string en datetime.

    Je suis vraiment bloqué.

    Quelqu'un pourrait-il m'éclairer ?

    Merci d'avance.

    Cordialement.

    mercredi 14 mars 2018 13:22

Réponses

  • Bonjour,

    Ça y est, la problématique est résolue, je pourrais a nouveau avancer dans mon projet. Je tiens à vous remercier, de m'avoir mis sur la voie.

    Voici le code fonctionnel, qui pourrais servir :

    Voici le code pour la source de données :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.Data;
    using Excel = Microsoft.Office.Interop.Excel;
    
    namespace WPFReadExcel
    {
        public class ExcelData
        {
            public DataView Data
            {
                get
                {
                    Excel.Application excelApp = new Excel.Application();
                    Excel.Workbook workbook;
                    Excel.Worksheet worksheet;
                    Excel.Range range;
                    workbook = excelApp.Workbooks.Open(Environment.CurrentDirectory + "\\Excel.xlsx");
                    worksheet = (Excel.Worksheet)workbook.Sheets["Test Sheet"];
    
                    int column = 0;
                    int row = 0;
    
                    range = worksheet.UsedRange;
                    DataTable dt = new DataTable();
                    dt.Columns.Add("ID");
                    dt.Columns.Add("Name");
                    dt.Columns.Add("Position");
                    dt.Columns.Add("WebSite");
                    dt.Columns.Add("Date");
    
                    for (row = 2; row <= range.Rows.Count; row++)
                    {
                        DataRow dr = dt.NewRow();
                        for (column = 1; column <= range.Columns.Count; column++)
                        {
                            dr[column - 1] = (range.Cells[row, column] as Excel.Range).Value2;                     
                        }
                        dt.Rows.Add(dr);
                        dt.AcceptChanges();
                    }
                    workbook.Close(true, Missing.Value, Missing.Value);
                    excelApp.Quit();
                    return dt.DefaultView;
                }
            }
    
        }
    }
    

    Voici le code XAML :

    <Window x:Class="WPFReadExcel.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:converter="clr-namespace:WPFReadExcel.Converter"            
            Height="226" Width="400">
        <Window.Resources>
            <converter:StringToDateConverter x:Key="MyConverter"/>       
        </Window.Resources>
        <Grid>
            <DataGrid Name="dataGrid1" AutoGenerateColumns="False" ItemsSource="{Binding Data}">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ID" Binding="{Binding ID}" />
                    <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
                    <DataGridTextColumn Header="Position" Binding="{Binding Position}" />
                    <DataGridTextColumn Header="Web Site" Binding="{Binding WebSite}" />
                    <DataGridTextColumn Header="Date" Binding="{Binding Date, Converter={StaticResource MyConverter}, StringFormat={}{0:dd/MM/yyyy}}" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>

    Le code pour le Convertisseur IValueConverter (pour convertir format date OLE vers Datetime) :

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Data;
    
    namespace WPFReadExcel.Converter
    {
        [ValueConversion(typeof(double), typeof(double))]
        public class StringToDateConverter : IValueConverter
        {
            #region IValueConverter Members
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                double Date = System.Convert.ToDouble(value);            
                DateTime dt = DateTime.FromOADate(Date);
                return dt;            
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return value;
            }
    
            #endregion
        }
    }

    Et enfin le programma principal :

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Markup;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    
    namespace WPFReadExcel
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
                Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
                this.Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentUICulture.Name);
                ExcelData exceldata = new ExcelData();
                this.dataGrid1.DataContext = exceldata;
            }       
        }
    }

    Encore une fois, merci pour l'aide que vous m'avez apporter.

    Cordialement.

    • Marqué comme réponse Kensi22 vendredi 16 mars 2018 03:48
    vendredi 16 mars 2018 03:48

Toutes les réponses

  • Bonjour Kensi22, 

    quel est le format de base pour StartDate ? (celui envoyé par Excel)

    Cordialement

    mercredi 14 mars 2018 13:34
  • Bonjour, et merci de l’intérêt que vous portez à cette problématique.

    Il me semble que la chaine retournée pour StartDate est au format texte (string).

    Par exemple, sur le fichier excel, la date est de la forme 26/04/1973. lors de l'importation vers la Datagrid, cette date est de la forme 26780.

    Par contre, je ne sais pas comment m'en assurer, ni comment la transformer au bon format.

    Merci d'avance.

    Cordialement.

    mercredi 14 mars 2018 15:05
  • Hum, je pense que c'est pour ça que le formatter n'arrive pas à faire son travail, 26780 représente une date sous format OLE, vous devez la convertir avant de l'insérer dans votre datagrid :

    DateTime dt = DateTime.FromOADate(26780);

    Cordialement, 

    mercredi 14 mars 2018 15:33
  • Bonjour,

    Voici comment j'ai utilisé ces informations :

    J'ai créé une classe IValueConverter :

    public class StringToDateConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {

                double Date=(double)value;
                DateTime dt = DateTime.FromOADate(Date);
                return dt;
            }

            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return value;
            }
        } }

    et le code XAML est modifier comme ceci :

    <DataGridTextColumn Header="StartDate" Binding="{Binding Date, Converter={StaticResource MyConverter}}" />
    Cette fois-ci, une erreur (exception non gérée) apparait : "System.InvalidCastException : 'Le cast spécifié n'est pas valide.'"

    Merci de votre aide.

    Cordialement.

    • Marqué comme réponse Kensi22 jeudi 15 mars 2018 11:19
    • Non marqué comme réponse Kensi22 jeudi 15 mars 2018 11:19
    mercredi 14 mars 2018 20:03
  • Bonjour,

    Ça y est, la problématique est résolue, je pourrais a nouveau avancer dans mon projet. Je tiens à vous remercier, de m'avoir mis sur la voie.

    Voici le code fonctionnel, qui pourrais servir :

    Voici le code pour la source de données :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.Data;
    using Excel = Microsoft.Office.Interop.Excel;
    
    namespace WPFReadExcel
    {
        public class ExcelData
        {
            public DataView Data
            {
                get
                {
                    Excel.Application excelApp = new Excel.Application();
                    Excel.Workbook workbook;
                    Excel.Worksheet worksheet;
                    Excel.Range range;
                    workbook = excelApp.Workbooks.Open(Environment.CurrentDirectory + "\\Excel.xlsx");
                    worksheet = (Excel.Worksheet)workbook.Sheets["Test Sheet"];
    
                    int column = 0;
                    int row = 0;
    
                    range = worksheet.UsedRange;
                    DataTable dt = new DataTable();
                    dt.Columns.Add("ID");
                    dt.Columns.Add("Name");
                    dt.Columns.Add("Position");
                    dt.Columns.Add("WebSite");
                    dt.Columns.Add("Date");
    
                    for (row = 2; row <= range.Rows.Count; row++)
                    {
                        DataRow dr = dt.NewRow();
                        for (column = 1; column <= range.Columns.Count; column++)
                        {
                            dr[column - 1] = (range.Cells[row, column] as Excel.Range).Value2;                     
                        }
                        dt.Rows.Add(dr);
                        dt.AcceptChanges();
                    }
                    workbook.Close(true, Missing.Value, Missing.Value);
                    excelApp.Quit();
                    return dt.DefaultView;
                }
            }
    
        }
    }
    

    Voici le code XAML :

    <Window x:Class="WPFReadExcel.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:converter="clr-namespace:WPFReadExcel.Converter"            
            Height="226" Width="400">
        <Window.Resources>
            <converter:StringToDateConverter x:Key="MyConverter"/>       
        </Window.Resources>
        <Grid>
            <DataGrid Name="dataGrid1" AutoGenerateColumns="False" ItemsSource="{Binding Data}">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ID" Binding="{Binding ID}" />
                    <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
                    <DataGridTextColumn Header="Position" Binding="{Binding Position}" />
                    <DataGridTextColumn Header="Web Site" Binding="{Binding WebSite}" />
                    <DataGridTextColumn Header="Date" Binding="{Binding Date, Converter={StaticResource MyConverter}, StringFormat={}{0:dd/MM/yyyy}}" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>

    Le code pour le Convertisseur IValueConverter (pour convertir format date OLE vers Datetime) :

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Data;
    
    namespace WPFReadExcel.Converter
    {
        [ValueConversion(typeof(double), typeof(double))]
        public class StringToDateConverter : IValueConverter
        {
            #region IValueConverter Members
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                double Date = System.Convert.ToDouble(value);            
                DateTime dt = DateTime.FromOADate(Date);
                return dt;            
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return value;
            }
    
            #endregion
        }
    }

    Et enfin le programma principal :

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Markup;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    
    namespace WPFReadExcel
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
                Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
                this.Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentUICulture.Name);
                ExcelData exceldata = new ExcelData();
                this.dataGrid1.DataContext = exceldata;
            }       
        }
    }

    Encore une fois, merci pour l'aide que vous m'avez apporter.

    Cordialement.

    • Marqué comme réponse Kensi22 vendredi 16 mars 2018 03:48
    vendredi 16 mars 2018 03:48