Outlook Add In

0

Witam wszystkich😊
Błądzę jak dziecko we mgle… Dostałem zadanko z dziedziny, w której jestem całkowitym newbie (nawet się zastanawiałem, czy to nie tam powinienem umieścić mój post). Mam zrobić Outllook Add In. Dodanie przycisku do Ribbon poszło. Teraz rozszerzenie do Appointment.
Kilka check i textboxów na nowej formie. Znalazłem doku na MSDN i zacząłem wczoraj próbować.
Większość dokumentacji mówi, że nowy „form region” można stworzyć w samym Outlooku i zaimportować do projektu. Tam też nie ma problemu ze zdefiniowaniem dodatkowych pól, żeby dane zostawały zachowane. Ale pojawił się pierwszy mały problem – korzystam z Outlooka 2016 i VS nie importuje pliku „.ofs”, tylko wyrzuca błąd „the installation path for office 15 cannot be determined”. OK, Microsoft przyznaje> „jest bug”. Rozwiązanie proponowane (https://social.msdn.microsoft.com/Forums/vstudio/en-US/3688eec8-2215-482c-ba5f-73f516ad26b8/unable-to-import-outlook-2016-form-region-ofs-into-visual-studio-2015-with-error-the?forum=vsto). Odinstaluj 2016 zainstaluj 2013 nie wchodzi w grę.
Inna droga to VS Designer, więc co tam. Dwa elementy na Formę i ta…

  1. Jak rozszerzyć AppointmentItem, żeby móc zapisać i odczytać przy ponownym otwarciu dane z dodatkowej formy (form region)? Powiedzmy w FormRegion.Designer.cs mam standardowy
    private System.Windows.Forms.TextBox textBoxVisitReason;
    private System.Windows.Forms.CheckBox checkBoxCoffee;
    to jaka jest dalsza droga?
    W klasie region form? W AddIn? Cos tam 100 razy zmieniałem i próbowałem... (i głupi jestem tak jak byłem:))

W

partial class MeetingFormRegion
   {

     #region Fields
      Outlook.AppointmentItem appointmentItem;
      // hmmm
      Outlook.ItemProperty  CheckBoxCoffee;
      // hmmhmm
      Outlook.OlkTextBox TextBoxVisitReason;

      #endregion
      #region Form Region Factory 

      [Microsoft.Office.Tools.Outlook.FormRegionMessageClass( Microsoft.Office.Tools.Outlook.FormRegionMessageClassAttribute.Appointment )]
      [Microsoft.Office.Tools.Outlook.FormRegionName( "MeetingExtendAddIn.MeetingFormRegion" )]
      public partial class MeetingFormRegionFactory
      {
         // Occurs before the form region is initialized.
         // To prevent the form region from appearing, set e.Cancel to true.
         // Use e.OutlookItem to get a reference to the current Outlook item.
         private void MeetingFormRegionFactory_FormRegionInitializing( object sender, Microsoft.Office.Tools.Outlook.FormRegionInitializingEventArgs e )
         {
         }
      }

      #endregion

      // Occurs before the form region is displayed.
      // Use this.OutlookItem to get a reference to the current Outlook item.
      // Use this.OutlookFormRegion to get a reference to the form region.
      private void MeetingFormRegion_FormRegionShowing( object sender, System.EventArgs e )
      {
         appointmentItem = this.OutlookItem as Outlook.AppointmentItem;

//jak najlepiej sprawdzic czy obecny meeting byl zapisany z dodatkowymi properties?
//Nowa Wrapper class, która implementuje interface?? Trochę overhead😐
/*namespace MeetingExtendAddIn
{
   public class MeetingAppointmentItem : Microsoft.Office.Interop.Outlook.AppointmentItem
   {
   }
}

i wtedy
            appointmentItem = this.OutlookItem as MeetingAppointmentItem;
           this.CheckBoxCoffee.Value =  MeetingAppointmentItem?.CheckBoxCoffee.Value.... czy jakos tam
*/ 
        // tak dodac wszytskie kontrolki?
         CheckBoxCoffee = appointmentItem.ItemProperties.Add( "CheckBoxCoffee", Outlook.OlUserPropertyType.olYesNo, true );
           }

      // Occurs when the form region is closed.
      // Use this.OutlookItem to get a reference to the current Outlook item.
      // Use this.OutlookFormRegion to get a reference to the form region.
      private void MeetingFormRegion_FormRegionClosed( object sender, System.EventArgs e )
      {
      }
      //test
      private void CheckBoxCoffe_CheckedChanged( object sender, EventArgs e )
      {
         CheckBoxCoffee.Value = checkBoxCoffee.Checked;
      }
  }

Czy może gdzieś tu instancja formy...

namespace MeetingExtendAddIn
{
   public partial class ThisAddIn
   {
      #region Fields
      Outlook.Application app;
      Outlook.Inspectors inspectors;
      Outlook.Folder folder;
      public stdole.IPictureDisp buttonPicture;
      internal static Office.IRibbonExtensibility myRibbon;
      
      #endregion
      
      private void ThisAddIn_Startup( object sender, System.EventArgs e )
      {
         // Current Application object - represents the whole application
         app = this.Application;
         // Current applikation's inspectors
         inspectors = app.Inspectors;

         // Add a new window (new inspector)
         inspectors.NewInspector += new Outlook.InspectorsEvents_NewInspectorEventHandler( Inspectors_ExtendAppointment );
         //set  icon for new button
         buttonPicture = PictureConverter.IconToPictureDisp( Icon.ExtractAssociatedIcon( "Images/OxygenStatusMailTask.ico" ));
         // To detect existing appointments we have to have current folder object
         folder = (Outlook.Folder)app.Session.GetDefaultFolder( Outlook.OlDefaultFolders.olFolderCalendar );
        
      }

      private void Inspectors_ExtendAppointment( Outlook.Inspector inspector )
      {
         //
         Outlook.AppointmentItem appointmentItem = inspector.CurrentItem as Outlook.AppointmentItem;

         //?? check if Appointment was saved with custom Properties?? here??
         //  if (appointment.kur_WtfProp != null) ??
         //      formRegion.Wtf = appointment.kur_WTFProp??

         //var newM = new MeetingFormRegion();
         Outlook.ItemProperty cbTest = appointmentItem.ItemProperties.Add( "CheckBoxCoffee", Outlook.OlUserPropertyType.olYesNo,true);
         Outlook.ItemProperty tbTest = appointmentItem.ItemProperties.Add( "TextBoxVisitReason", Outlook.OlUserPropertyType.olText, true );

         //cbtest.Value = MeetingFormRegion.CheckBoxCoffe.Checked ;

      }

      private void ThisAddIn_Shutdown( object sender, System.EventArgs e )
      {
         // Note: Outlook no longer raises this event. If you have code that 
         // must run when Outlook shuts down, see http://go.microsoft.com/fwlink/?LinkId=506785

         // Unhook event handler
         inspectors.NewInspector -= new Outlook.InspectorsEvents_NewInspectorEventHandler( Inspectors_ExtendAppointment );
         
         buttonPicture = null;
         myRibbon = null;
         inspectors = null;
         folder = null;
         app = null;
      }

      //Must be overwritten to display custom Ribbon
      protected override Office.IRibbonExtensibility CreateRibbonExtensibilityObject()
      {
         return new Ribbon();
      }

      #region VSTO generated code

      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      private void InternalStartup()
      {
         this.Startup += new System.EventHandler( ThisAddIn_Startup );
         this.Shutdown += new System.EventHandler( ThisAddIn_Shutdown );
      }

      #endregion

Tak jak napisałem, bładzę jak dziecko we mgle. kompletnie nie czuję tematu:( Z tego względu z góry przepraszam, jeśli pytania są tak bez sensu, że obrażają inteligencję czytających:)
Jakieś linki, podpowiedzi, komentarze, pls.

A tak na marginesie, to mam te moją porażkę potem dodać na server, żeby nowa forma była w firmie dostepna... Już zaczynam sobie grób kopać:)
Add Ins \ Exchange \ ofice development - nigdy nie miałem z tym do czynienia, hihihi.
Ale jak to w pracy - "...ale przecież Pan C# cos tam...blabla..no, to trzeba szybko dopisać...potem jakies raporty będą potrzebne... no nie w outlooku, to ogranicza gdzieś mówili... w kodzie Pan napisze szybko.."
:| i teraz błądzę... :|

0

Witka,
a wiec znalazłem taką drogę. Żadnych zmian w ThissAddIn.cs. Dodatkowa klasa z custom properties, początek..

public class MeetingAppointmentItem
   {

      public Outlook.AppointmentItem appointmentItem;
      public Outlook.UserProperty  CheckBoxCoffee;
      public Outlook.UserProperty  TextBoxVisitReason;
      public Outlook.UserProperty TextBoxSpecials;

      public MeetingAppointmentItem( Outlook.AppointmentItem appointmentItem )
      {
         this.appointmentItem = appointmentItem;
         CheckBoxCoffee = appointmentItem.UserProperties.Find( "CheckBoxCoffee" );
         TextBoxVisitReason = appointmentItem.UserProperties.Find( "TextBoxVisitReason" );
         if( CheckBoxCoffee == null )
            CheckBoxCoffee = appointmentItem.UserProperties.Add( "CheckBoxCoffee", Outlook.OlUserPropertyType.olYesNo, true, true );
         if( TextBoxVisitReason == null )
            TextBoxVisitReason = appointmentItem.UserProperties.Add( "TextBoxVisitReason", Outlook.OlUserPropertyType.olText, true, true );
         if( appointmentItem.UserProperties.Find( "TextBoxSpecials" ) == null)
            TextBoxSpecials = appointmentItem.UserProperties.Add( "TextBoxSpecials", Outlook.OlUserPropertyType.olText, true, true );
      }
 }

i w klasie formy

 #region Fields
      MeetingAppointmentItem meetingAdapter;
  #endregion
.......
     // Occurs before the form region is displayed.
      // Use this.OutlookItem to get a reference to the current Outlook item.
      // Use this.OutlookFormRegion to get a reference to the form region.
      private void MeetingFormRegion_FormRegionShowing( object sender, System.EventArgs e )
      {
         meetingAdapter = new MeetingAppointmentItem( this.OutlookItem as Outlook.AppointmentItem );
         checkBoxCoffee.Checked = meetingAdapter.CheckBoxCoffee.Value;
         textBoxVisitReason.Text = meetingAdapter.TextBoxVisitReason.Value;
         textBoxSpecials.Text = meetingAdapter.TextBoxSpecials.Value;
      }

      // Occurs when the form region is closed.
      // Use this.OutlookItem to get a reference to the current Outlook item.
      // Use this.OutlookFormRegion to get a reference to the form region.
      private void MeetingFormRegion_FormRegionClosed( object sender, System.EventArgs e )
      {
         meetingAdapter.appointmentItem.Save();
      }
      //test
      private void CheckBoxCoffe_CheckedChanged( object sender, EventArgs e )
      {
         meetingAdapter.CheckBoxCoffee.Value = checkBoxCoffee.Checked;
      }
      //test
      private void textBoxVisitReason_TextChanged( object sender, EventArgs e )
      {
        meetingAdapter.TextBoxVisitReason.Value = textBoxVisitReason.Text;
      }
.......

Z jednej strony może się komus przyda, z drugiej może teraz łatwiej zauważyć, co powinienem poprawić. Każda uwaga się przyda:)
Pozdrawiam

0 użytkowników online, w tym zalogowanych: 0, gości: 0