I created an Office Add-In project and I added ribbon menu for application. When I build my project word document have my ribbon there is no problem.
How can I save the active document as a file using StreamReader when clicking on a button from the ribbon menu using the button click event below?
private void btnsavefile_Click(object sender, RibbonControlEventArgs e)
{
//Getting FileStream here.
}
I found the following solution in Stack Overflow. Hopefully it is relevant to you.
Serialize current ActiveDocument from office 2007 add-in
Personally, I have done the same when I was dealing with this scenario. I have saved a copy of the file to the temporary location and pushed the copy to the server. In this case, the active document stays as is.
Excel.Workbook xlb = Globals.ThisAddIn.Application.ActiveWorkbook;
xlb.SaveCopyAs(filePath);
Hope this helps!
void Application_DocumentBeforeClose(Word.Document document, ref bool Cancel)
{
try
{
string filePath = this.Application.ActiveDocument.FullName.ToString();
string fileName = this.Application.ActiveDocument.Name;
//dialogFilePath = filePath;
dialogFileName = fileName;
string tempFile;
string tempPath;
if (true)
{
var confirmResult = System.Windows.Forms.MessageBox.Show("Are you sure to save this document ??",
"Confirm Save!!",
System.Windows.Forms.MessageBoxButtons.YesNo);
if (confirmResult == System.Windows.Forms.DialogResult.Yes)
{
//document.Save();
var iPersistFile = (IPersistFile)document;
iPersistFile.Save(tempPath, false);
//Do some action here
}
Word._Document wDocument = Application.Documents[fileName] as Word._Document;
//wDocument.Close(Word.WdSaveOptions.wdDoNotSaveChanges);
ThisAddIn.doc.Close(Word.WdSaveOptions.wdDoNotSaveChanges);
}
}
catch (Exception exception)
{
}
}
Create Word Addin project-> Add Ribbon visual designer from add new item.
Add menu to Ribbon designer and write below code in ribbonsample.cs
public partial class RibbonSample
{
private void RibbonSample_Load(object sender, RibbonUIEventArgs e)
{
// Initialise log4net
}
//Adding items in menu from DB
public RibbonSample()
: base(Globals.Factory.GetRibbonFactory())
{
InitializeComponent();
try
{
System.Data.DataTable dt = new DataAcces().GetData();
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
RibbonButton Field = this.Factory.CreateRibbonButton();
Field.Label = dt.Rows[i][1].ToString();
Field.Tag = i;
Field.ControlSize =
Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
Field.Click += Field_Click;
menu1.Items.Add(Field);
}
}
else
{
System.Windows.Forms.MessageBox.Show("No Fields are available in database");
}
}
catch (Exception exception)
{
//thrw exception
}
}
//Select menu item text in word
void Field_Click(object sender, RibbonControlEventArgs e)
{
try
{
Microsoft.Office.Interop.Word.Range currentRange = Globals.ThisAddIn.Application.Selection.Range;
currentRange.Text = (sender as RibbonButton).Label;
}
catch (Exception exception)
{
log.Error(friendlyErrorMessage + " Field_Click Details:" + exception.Message, exception);
}
}
}
Related
I've created simple addin for Outlook 2010 that replace specific phrase with link, for example I want to replace ABC12345 with http://www.example.com?id=123456
I'm using this code:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
inspectors = this.Application.Inspectors;
inspectors.NewInspector += new Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
}
void Inspectors_NewInspector(Outlook.Inspector Inspector)
{
var mailItem = Inspector.CurrentItem as Outlook.MailItem;
if (mailItem != null)
{
if (mailItem.EntryID != null)
{
string pattern = #"ABC(?<number>\d{1,6})";
var match = Regex.Match(mailItem.HTMLBody, pattern);
if (match.Success)
{
var replaced = Regex.Replace(mailItem.HTMLBody, pattern, m => "ABC"+ m.Groups["number"].Value+"");
mailItem.HTMLBody = replaced;
}
}
}
}
However I have two issues:
I must double click email in mailbox to have my event fired. I want to display that link when previewing emails (moving up and down in mailbox)
My code is replacing content, so Outlook "thinks" I've made some changes and when I want to close window it asks if I want to save those changes.
I don't want to alter body of email, I want to change phrase ABC123456 into link.
EDIT1:
I've tried using ActiveExplorer, this allows me to access email in preview window, but when I change email body those changes are saved. My intention is to change how specific text is displayed (change it to link), but not to alter email body on serwer.
I want those changes to be visible in my instance of Outlook, not saved on server (mailItem.HTMLBody.Replace does that).
Can I access view that displays email and alter that view?
This is the code:
Outlook.Explorer currentExplorer;
private void ThisAddIn_Startup(object sender, EventArgs e)
{
currentExplorer = this.Application.ActiveExplorer();
currentExplorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(CurrentExplorer_Event);
}
private void CurrentExplorer_Event()
{
var selectedFolder = this.Application.ActiveExplorer().CurrentFolder;
try
{
if (this.Application.ActiveExplorer().Selection.Count > 0)
{
var selObject = this.Application.ActiveExplorer().Selection[1];
if (selObject is Outlook.MailItem)
{
Outlook.MailItem mailItem = (selObject as Outlook.MailItem);
mailItem.HTMLBody = mailItem.HTMLBody.Replace("ABC", "DEF");
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
EDIT2
I'm able to get WordEditor inside Outlook, but I can't add hyperlink.
Last think I want now is to find specific phrases in email and add hyperlink to them. Here is my current code:
Outlook.Explorer currentExplorer;
private void ThisAddIn_Startup(object sender, EventArgs e)
{
currentExplorer = this.Application.ActiveExplorer();
currentExplorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(CurrentExplorer_Event);
}
private void CurrentExplorer_Event()
{
var selectedFolder = this.Application.ActiveExplorer().CurrentFolder;
try
{
if (this.Application.ActiveExplorer().Selection.Count > 0)
{
var selectedObject = this.Application.ActiveExplorer().Selection[1];
if (selectedObject is Outlook.MailItem)
{
var mail = (selectedObject as Outlook.MailItem);
var inspector = mail.GetInspector;
if (inspector.IsWordMail())
{
var document = (Document)inspector.WordEditor;
if (document != null)
{
var app = document.Application;
var find = document.Range().Find;
find.Text = "ABC";
while (find.Execute())
{
var rng = find.Parent as Range;
rng.Hyperlinks.Add(rng, "http://example.com/?query=" + rng.Text );
rng.Collapse(WdCollapseDirection.wdCollapseEnd);
}
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
I have created a notepad with a tabbed interface. It is a c# winform application. Now, what I want is this - if the file does not exist anymore, deleted by another program then if I click the related tab, it should show a message that "the file does not exist" and it should close the tab.
private string FolderPath = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); // location of document folder
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabControl1.TabCount == 0)
{
return;
}
else
{
TabPage tpp = tabControl1.SelectedTab;
this.FileOnly = tpp.Text + ".txt"; // I used tab names without extension, that's why adding it back
String str = tpp.Text;
string CorrFolderPath = FolderPath.Replace(#"\", #"\\");
string FolderPathcomplete = CorrFolderPath + "\\My_Note\\"; // this is the location of saving files; the folder contents appear as list box entries in the program
string filename = FolderPathcomplete + FileOnly;
if (str.Contains("New Document"))// the new tabs which are not yest saved has the name New Document 1, 2 etc.
{
return;
}
else
{
if (File.Exists(filename))
{
return;
}
else
{
MessageBox.Show("File does not exist! Closing the tab.");
var tabPage = tabControl1.TabPages[str];
tabControl1.TabPages.RemoveByKey(str);
}
}
}
}
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
TabPage tp = new TabPage("New Document" + count); //creates a new tab page
tp.Name = "New Document" + count;
RichTextBox rtb = new RichTextBox(); //creates a new richtext box object
tp.Controls.Add(rtb); // adds rich text box to the tab page
tabControl1.TabPages.Add(tp); //adds the tab pages to tab control
tabControl1.SelectedTab = tp;
tabControl1.SelectedIndexChanged += tabControl1_SelectedIndexChanged; // it will check whether tab file exists or not
this.FileName = string.Empty;
count++;
}
Consider using a FileSystemWatcher -- where on creation of a new tab, you create a new watcher and monitor for any changes.
See this article for more information:
https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx
I am trying to trigger and event after the WokbookDeactivate event is finished because I need to write some metadata into the file and it can be done only when the Excel file is completely closed.
While using WokbookDeactivate the workbook still appears as active and if I try to run the code that access the excel file it raises an exception "is being used by another process..."
ThisAddin_Startup
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.WorkbookOpen += new Excel.AppEvents_WorkbookOpenEventHandler(Application_WorkbookOpen);
this.Application.WorkbookDeactivate += Application_WorkbookDeactivate;
}
EventHandler
void Application_WorkbookDeactivate(Microsoft.Office.Interop.Excel.Workbook Wb)
{
Excel.Application excelApp = this.Application;
string filePath = excelApp.ActiveWorkbook.FullName;
string userName = GeneralFunctions.getUser();
try
{
if (File.Exists(filePath) && Metadata.ContainsKey(filePath) && Metadata[filePath])
{
Metadata.Remove(filePath);
}
}
catch (Exception)
{
throw;
}
finally
{
}
}
After Deactivate I need to run another event that check if the key of the excel file was removed from the Metadata. That means I can edit the document using the OpenXML function...
I tried to attach two events to the Deactivate, but the excel workbook is still open when the first one finishes.
Any idea?
Another approach:
I created a Timer property System.Timers.Timer _tm; and call a method to initialize it.
void Application_WorkbookDeactivate(Excel.Workbook Wb)
{
Excel.Application excelApp = this.Application;
string filePath = excelApp.ActiveWorkbook.FullName;
try
{
if (File.Exists(filePath) && Metadata.ContainsKey(filePath) && Metadata[filePath] && Wb.FullName.Equals(filePath))
{
StartWrite(filePath);
}
}
catch (Exception)
{
throw;
}
}
private void StartWrite(string filePath)
{
_tm = new System.Timers.Timer(2000);
_tm.Elapsed += (sender, args) => _tm_Elapsed(sender, filePath);
_tm.Enabled = true;
}
void _tm_Elapsed(object sender, string filePath)
{
try
{
((System.Timers.Timer)sender).Enabled = false;
string userName = GeneralFunctions.getUser();
if (this.Application != null && Metadata[filePath])
{
// Do stuff with the file
_tm.Stop();
}
}
catch (Exception)
{
throw;
}
}
I am just starting out with a Word VSTO Add-in. I want to add a group to the ribbon, which has a button to toggle a custom task pane. I want each document to have it's own independent task pane. I have this mostly working, but there is one situation that doesn't work:
Start Word - new document opened, all works fine
Open existing document (closes empty document)
Click on toggle button, pane doesn't appear
Create new document or open ANOTHER existing document, pane appears on that document
Pane now works as expected on all documents, including the problem one from 2/3.
Note that if you type something into the new document (1), everything works as expected, so this seems to be something to do with the existing document loading over the top of the initial empty one, but I can't work out what's going on.
Here's my code from ThisAddIn class:
Note that the PaneControl is a totally empty User Control, behaviour doesn't change when I add stuff to it.
public partial class ThisAddIn
{
private CustomTaskPane CurrentTaskPane(Object window)
{
foreach (CustomTaskPane ctp in CustomTaskPanes)
{
if (ctp.Window.Equals(window))
{
return ctp;
}
}
return null;
}
public bool ToggleTaskPane(Object window)
{
CustomTaskPane ctp = CurrentTaskPane(window);
if (ctp != null)
{
ctp.Visible = !ctp.Visible;
return ctp.Visible;
}
else
{
return false;
}
}
private void RemoveOrphanedTaskPanes()
{
for (int i = CustomTaskPanes.Count; i > 0; i--)
{
var ctp = CustomTaskPanes[i - 1];
if (ctp.Window == null)
{
CustomTaskPanes.Remove(ctp);
}
}
}
private void CreateTaskPane(Object window)
{
try
{
RemoveOrphanedTaskPanes();
// Add the new one
PaneControl ucPaneControl = new PaneControl();
CustomTaskPane ctp = CustomTaskPanes.Add(ucPaneControl, "Test Pane", window);
ctp.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
ctp.Width = 300;
}
catch
{
MessageBox.Show("Unable to create pane");
}
}
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
try
{
Word.ApplicationEvents4_Event app = (Word.ApplicationEvents4_Event)Application; // Disambiguate
app.DocumentOpen += new Word.ApplicationEvents4_DocumentOpenEventHandler(Application_DocumentOpen);
app.NewDocument += new Word.ApplicationEvents4_NewDocumentEventHandler(Application_NewDocument);
app.DocumentChange += new Word.ApplicationEvents4_DocumentChangeEventHandler(Application_DocumentChange);
CreateTaskPane(Application.ActiveWindow);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
RemoveOrphanedTaskPanes();
}
void Application_DocumentChange()
{
RemoveOrphanedTaskPanes();
}
void Application_DocumentOpen(Word.Document Doc)
{
// Creeate pane for existing document
CreateTaskPane(Doc.ActiveWindow);
}
void Application_NewDocument(Word.Document Doc)
{
// Creeate pane for new blank document
CreateTaskPane(Doc.ActiveWindow);
}
#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
The code attached to the ribbon button is:
Globals.ThisAddIn.ToggleTaskPane(Globals.ThisAddIn.Application.ActiveWindow);
Any ideas why this might be happening?
Thanks
ROSCO
Does any one know how to provide file name to the exported file in Telerik RadGrid,
Exported file could be of any format pdf, excel or word
Source: Grid / MS Excel/MS Word/CSV
Use RadGrid.ExportSettings.FileName property, a string specifying the
name (without the extension) of the file that will be created. The
file extension is automatically added based on the method that is used
Try setting the FileName in the ItemCommand event as shown below.
From: When to set RadGrid.ExportSettings.FileName
protected void Radgrid1_ItemCommand(object sender, GridCommandEventArgs e)
{
if (e.CommandName == RadGrid.ExportToPdfCommandName)
{
Radgrid1.ExportSettings.FileName = "yourfilename";
}
if (e.CommandName == RadGrid.ExportToExcelCommandName)
{
Radgrid1.ExportSettings.FileName = "yourfilename";
}
if (e.CommandName == RadGrid.ExportToWordCommandName)
{
Radgrid1.ExportSettings.FileName = "yourfilename";
}
}
Reference:
Export RadGrid content to Excel/Word/CSV/PDF with Ajax enabled
You can set the filename as well as other options for exporting, on the ExportSettings property of the grid (not the MasterTableView). So for example:
myGrid.ExportSettings.FileName = "file";
myGrid.ExportSettings.Excel.Extension = "xls";
myGrid.MasterTableView.ExportToExcel();
try
{
object districtid = Session["DistID"];
RadGrid tempGrid = rgDupEmpoyees;
string fileName = "LEA_" + districtid .ToString() + "_PossibleNoShowTonySopranoEmployees_" + DateTime.Now.ToString("dd_MMM_yyyy");
tempGrid.ExportSettings.FileName = fileName;
tempGrid.ClientSettings.Scrolling.UseStaticHeaders = false;
tempGrid.MasterTableView.ExportToPdf();
}
catch (Exception ex)
{
this.LogException(ex);
DisplayPageMessage(ex.GetBaseException().Message, PageMessageType.Error);
//e.Cancel = true;
}
finally
{
this.LogMethodExit();
}