giovedì 4 settembre 2014

Set the DecodePixelHeight property (Binding) of the BitmapImage object from the configuration file

C# .NET Framework 4.0 (WPF - MVVM)

In my MVVM WPF application, I want to resize a bitmap image with values stored in app.config. Therefore, for doing this I’ve tried to bind the Image.Height property and the BitmapImage.DecodePixelHeight directly to my ViewModel, like in this way:

In app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>   
  <appSettings>   
    <add key="DocumentsToBeFiledImageHeight" value="240"/>
    <add key="DocumentsToBeFiledImageDecodePixelHeight" value="240"/>
  </appSettings
</configuration>

Then in my ViewModel I’ve added these properties 

    private int _documentsToBeFiledImageDecodePixelHeight;
    public int DocumentsToBeFiledImageDecodePixelHeight
    {
      get { return _documentsToBeFiledImageDecodePixelHeight; }
      set
      {
        if (value != _documentsToBeFiledImageDecodePixelHeight)
        {
          _documentsToBeFiledImageDecodePixelHeight = value;
          RaisePropertyChanged(DocumentsToBeFiledImageDecodePixelHeightPropertyName);
        }
      }
    }

    private double _documentsToBeFiledImageHeight;
    public double DocumentsToBeFiledImageHeight
    {
      get { return _documentsToBeFiledImageHeight; }
      set
      {
        if (value != _documentsToBeFiledImageHeight)
        {
          _documentsToBeFiledImageHeight = value;
          RaisePropertyChanged(DocumentsToBeFiledImageHeightPropertyName);
        }
      }
    }

and this code

DocumentsToBeFiledImageHeight = Convert.ToDouble(ConfigurationManager.AppSettings["DocumentsToBeFiledImageHeight"]);

DocumentsToBeFiledImageDecodePixelHeight = Convert.ToInt32(ConfigurationManager.AppSettings["DocumentsToBeFiledImageDecodePixelHeight"]);

Then in the XAML I’ve added this code

<Image Grid.Row="0" Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.DocumentsToBeFiledImageHeight, UpdateSourceTrigger=PropertyChanged}"> 
  <Image.Source>
    <BitmapImage DecodePixelHeight="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.DocumentsToBeFiledImageDecodePixelHeight, UpdateSourceTrigger=PropertyChanged}" 
      UriSource="{Binding Path=FullName}" />
  </Image.Source>
</Image>

Unfortunately it doesn’t work, it seems that the DecodePixelHeight property is not set correctly.
Therefore, I’ve tried to recover the value directly from app.config. I’ve added these parameters in the user setting section in my app.config file

<userSettings>
    <Agest.AO.Client.Properties.Settings>
      <setting name="DocumentsToBeFiledImageDecodePixelHeight" serializeAs="String">
        <value>240</value>
      </setting>
<setting name="DocumentsToBeFiledImageHeight" serializeAs="String">
        <value>240</value>
      </setting>
    </Agest.AO.Client.Properties.Settings>
</userSettings

and I’ve changed the XAML code in this way

xmlns:localme="clr-namespace:Agest.AO.Client.Properties" 

<Image Grid.Row="0" Height="{Binding Source={x:Static localme:Settings.Default}, Path=DocumentsToBeFiledImageHeight, Mode=OneWay}">
  <Image.Source>
    <BitmapImage DecodePixelHeight="{Binding Source={x:Static localme:Settings.Default}, Path=DocumentsToBeFiledImageDecodePixelHeight, Mode=OneWay}"
            UriSource="{Binding Path=FullName}" />
  </Image.Source>
</Image>


Now it works and I’m able to set values directly in the configuration file.

Regards!

giovedì 26 giugno 2014

Export a list items in an excel file.

c# .NET 4.0 (WPF) - Excel 2013

I would like to export my list items (WPF ListView) in an excel file and I would like to do this using a generic mode.

I did it in this way:

        /// <summary>
        /// Exports to CSV.
        /// </summary>
        private void ExportToCsv()
        {
            string exportPath = ConfigurationManager.AppSettings["ExportToCsvPath"];
            if (!Directory.Exists(exportPath))
                Directory.CreateDirectory(exportPath);

            string fileName = Path.Combine(exportPath, "ExportActivities.csv");

            if (!Help.ExportToCsvStream(CreateDataGrid(), fileName))
            {
                string msg = String.Format(Strings.def_msgExportToCsvError, Environment.NewLine);
                MessageBox.Show(msg, MessageTitle, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// Creates the data grid.
        /// </summary>
        /// <returns></returns>
        private StringBuilder CreateDataGrid()
        {
            try
            {
                // These are the column headers of the excel file.
                String[] headersToExport =
                {
                    "UserName", "Municipality", "BinderName", "BoxNumber", "ImageNumber", "DiscardedImage",
                    "DocumentsNumber", "TotalPagesNumber", "StartDate", "EndDate", "SendDate", "ImportDate", "State"
                };

                // These are columns of the excel file and these are the properties that I want to export.
                String[] propertiesToExport =
                {
                    "PreferedUser.UserName", "Municipality", "BinderName", "BoxNumber", "ImageNumber", "DiscardedImage",
                    "DocumentsNumber", "TotalPagesNumber", "StartDate", "EndDate", "SendDate", "ImportDate", "State"
                };

                return Activities.ToCsv(headersToExport, propertiesToExport);
            }
            catch (Exception ex)
            {
                string msg = String.Format(Strings.def_msgExportToCsvError, Environment.NewLine);
                MessageBox.Show(msg, MessageTitle, MessageBoxButton.OK, MessageBoxImage.Error);

                Log.WriteLog(ex);
                return null;
            }
        }

        /// <summary>
        /// Exports to CSV stream.
        /// </summary>
        /// <param name="sb">The sb.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <returns></returns>
        public static bool ExportToCsvStream(StringBuilder sb, string fileName)
        {
            try
            {
                // Default ANSI code for csv file
                Encoding ansi = Encoding.GetEncoding(1252);
                byte[] csvBytes = ansi.GetBytes(sb.ToString());
               
                CreateAndOpenFile(csvBytes, fileName);

                return true;
            }
            catch (Exception ex)
            {               
                Log.WriteLog(ex);
                return false;
            }
        }

        /// <summary>
        /// Formats for CSV.
        /// </summary>
        /// <param name="dato">The dato.</param>
        /// <returns></returns>
        public static string FormatForCsv(string dato)
        {
            if (dato != null)
            {
                string datoFormatted = dato.Trim();

                if (string.IsNullOrEmpty(datoFormatted))
                    return string.Empty;

                datoFormatted =
                    datoFormatted
                        .Replace(Environment.NewLine, string.Empty)
                        .Replace(@"""", "'")
                        .Replace(";", ".");
               
                if (datoFormatted.Length > 255)
                    datoFormatted = datoFormatted.Substring(0, 255);

                return string.Format(@"=""{0}""", datoFormatted);
            }
            return string.Empty;
        }

        private static int _processIdExcel;
        /// <summary>
        /// Creates the and open file.
        /// </summary>
        /// <param name="bytes">The bytes.</param>
        /// <param name="filename">The filename.</param>
        private static void CreateAndOpenFile(byte[] bytes, string filename)
        {
            try
            {
                if (File.Exists(filename))
                {
                    CloseExcel();
                    File.Delete(filename);
                }

                using (var stream = new FileStream(filename, FileMode.Create, FileAccess.Write))
                {
                    stream.Write(bytes, 0, bytes.Length);
                }

                var process = Process.Start(filename);
                if (process != null) _processIdExcel = process.Id;
            }
            catch (Exception ex)
            {
                Log.WriteLog(ex);
                throw;
            }
        }

        /// <summary>
        /// Closes the excel.
        /// </summary>
        private static void CloseExcel()
        {
            try
            {
                if (_processIdExcel > 0)
                {
                    // The Excel process already exists and has been instantiated from us.
                    Process procExcel = Process.GetProcessById(_processIdExcel);
                    if (String.Equals(procExcel.ProcessName, "excel", StringComparison.OrdinalIgnoreCase))
                        procExcel.Kill();

                    _processIdExcel = 0;
                }
                else
                {
                    // The process has been instantiated but Excel does not check if there is anyway existence.
                    Process[] processes = Process.GetProcessesByName("Excel");
                    if (processes.Length > 0)
                    {
                        _processIdExcel = processes[0].Id;
                        CloseExcel();
                    }
                }
                Thread.Sleep(20);
            }
            catch (Exception ex)
            {
                Log.WriteLog(ex);
            }
        }

        /// <summary>
        /// Gets or sets the activities.
        /// </summary>
        /// <value>
        /// The activities.
        /// </value>
        public ObservableCollection<Activity> Activities
        {
            get { return _activities; }
            set
            {
                if (value != _activities)
                {
                    _activities = value;
                    RaisePropertyChanged(ActivitiesPropertyName);
                }
            }
        }

        /// <summary>
        /// To the CSV.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumerableList">The enumerable list.</param>
        /// <param name="headersToExport">The headers to export.</param>
        /// <param name="propertiesToExport">The properties to export.</param>
        /// <returns></returns>
        public static StringBuilder ToCsv<T>(this IEnumerable<T> enumerableList, String[] headersToExport,
            String[] propertiesToExport)
        {
            try
            {
                if (enumerableList != null)
                {
                    // Create the CSV file to which grid data will be exported.
                    var sb = new StringBuilder();
                    var typeParameterType = typeof (T);

                    #region Headers

                    foreach (string t in headersToExport)
                        sb.Append(String.Concat(t, ";"));

                    sb.Append(Environment.NewLine);

                    #endregion

                    #region Properties

                    var propertyInfos = typeParameterType.GetProperties();
                    foreach (var entity in enumerableList)
                    {
                        for (int index = 0; index < propertiesToExport.Length; index++)
                        {
                            String[] properties = propertiesToExport[index].Split(".".ToCharArray());

                            PropertyInfo property = null;
                            if (properties.Count() > 1)
                            {
                                #region If it is a composed property, like PreferedUser.UserName

                                var pInfos = propertyInfos;
                                object en = entity;

                                for (int i = 0; i < properties.Count(); i++)
                                {
                                    property = pInfos.FirstOrDefault(pi => pi.Name.Equals(properties[i]));

                                    if (property != null && en != null && i < properties.Count() - 1)
                                    {
                                        pInfos = property.PropertyType.GetProperties();
                                        en = property.GetValue(en, null);
                                    }
                                }

                                if (en != null)
                                {
                                    if (property != null && property.PropertyType == typeof (DateTime?))
                                    {
                                        if (property.GetValue(en, null) != null)
                                            sb.Append(
                                                String.Concat(
                                                    ((DateTime?) property.GetValue(en, null)).Value.ToItaFormat(), ";"));
                                        else
                                            sb.Append(";");
                                    }
                                    else if (property != null && property.PropertyType == typeof (DateTime))
                                    {
                                        sb.Append(
                                            String.Concat(
                                                ((DateTime) property.GetValue(entity, null)).ToItaFormat(), ";"));
                                    }
                                    else if (property != null)
                                        sb.Append(String.Concat(property.GetValue(en, null), ";"));
                                }
                                else
                                    sb.Append(";");

                                #endregion
                            }
                            else
                            {
                                int index1 = index;
                                property = propertyInfos.FirstOrDefault(pi => pi.Name.Equals(propertiesToExport[index1]));

                                if (property != null && property.PropertyType == typeof (DateTime?))
                                {
                                    if (property.GetValue(entity, null) != null)
                                        sb.Append(
                                            String.Concat(
                                                ((DateTime?) property.GetValue(entity, null)).Value.ToItaFormat(), ";"));
                                    else
                                        sb.Append(";");
                                }
                                else if (property != null && property.PropertyType == typeof (DateTime))
                                {
                                    sb.Append(
                                        String.Concat(
                                            ((DateTime) property.GetValue(entity, null)).ToItaFormat(), ";"));
                                }
                                else if (property != null)
                                    sb.Append(String.Concat(property.GetValue(entity, null), ";"));
                            }
                        }

                        sb.Append(Environment.NewLine);
                    }

                    #endregion

                    return sb;
                }
                return null;
            }
            catch
            {
                return null;
            }

        }

If you have any questions, please contact me as well.
See you again soon!