C# Copy powerpoint Master Slide layout - c#

I want to copy master layout from one presentation to another.
If I wanted to copy a slide the code would be Presentation.Slides[1].Copy, however I can't find similar code for copying master layout. There is Presentation.SlideMaster.Delete() but for some reason there is no copy. If it is not possible in c# is it possible in vba??
I want to basically automate this

This is the VBA code to copy a design from one presentation to the other - http://skp.mvps.org/pptxp018.htm. The same is achievable in C#.
Sub CopyDesigns()
Dim oSourceDesigns As Presentation
Dim I As Integer
Set oSourceDesigns = Presentations.Open("K:\Docs\main.pot", , , False)
For I = 1 To oSourceDesigns.Designs.Count
ActivePresentation.Designs.Clone oSourceDesigns.Designs(I)
Next I
oSourceDesigns.Close
Set oSourceDesigns = Nothing
End Sub

Related

How to display clickable directories on an aspx page without dynamically adding controls as subfolders

I created an aspx website which shows a directory with its content from a FTP-Server. If I click a folder inside this directory, it should display the content of the sub directory and so on.
What I have tried so far is to display the content of a directory as dynamically createt WebControls.Button. Those buttons have a onclick event difined in the c# code behind.
This is a bad idea because of the following reason:
Creating new dynamically controls after a postback (clicking on a folder) prevents any onclick event , added to the sub directory buttons, to work.
This is, because controls need an unique ID that eventhandling works properly.
Let me explain this with an example:
First page load -> every directory displayed gets an ID (1-7) and
an onclick event assigned.
Scenario 1:
Opening folder "Europe" with the ID 1 -> onclick
event gets fired -> the sub directories will be loaded in codebehind, displayed and get an ID (1- ..) and an onclick event assigned.
Opening the subfolder "Andorra" with ID 1 -> onclick event gets fired -> But now the parent folder "Europe" will be opened, because it already had ID 1.
Scenario 2
Opening folder "Europe" with the ID 1 -> onclick event gets fired -> the sub directories will be displayed, but now we assign new IDs (6-..) and the onclick event.
Opening the folder "Andorra" with the ID 6 -> onclick event does not get fired (event mechanism seems to be confused about the new ID) -> instead all the added buttons (directories) dissapear from the page.
Additional Info:
To know which button is clicked, I save the path in the Button.CommandArgument parameter, so the codebehind knows which directory to load from the FTP.
I really have no more ideas how to realize a simple clickable directory in asp.net.
I hope you understant the struggle and may have an idea to share :)
Ok, here is what you do.
Lets drag a button on a blank web form.
Next, drag and drop in a treeview.
On the treeview control, select this option: (auto format)
Now, you don't have to do the above auto format. All it does is "set up" the icons for a treeview. The built in list has typical bullets or > etc. And these are "just" settings in the property sheet for you. (you can use your own icons, but this sets them up for you).
Ok, so far, zero code.
Now, for our code behind the button to fill the treeview.
Dim myFiles As List(Of String) = GetAllFtpFiles(fRoot, UserId, Passwrod)
Call PopulateTreeViewFiles(fRoot, myFiles, "", Nothing)
The routine GetAllFtpFiles simple returns a list of files at a given starting folder.
So fRoot would be
"ftp://ftp.mywebsite/startingFolder/" (we do assume trailing /)
We then call PopulateTreeViewFiles. All it does add the list of base files. Now we COULD populate the WHOLE tree, but that can take a bit of time, so we only populate folders when clicked on.
So, the GetAllFtpFiles simple returns a list of files.
I am sure you ALREADY have your own FTP file get/grab/fetch routine, but here is the one I used:
Private Function GetAllFtpFiles(ByVal ParentFolderpath As String, UserId As String, Password As String) As List(Of String)
Try
Dim ftpRequest As FtpWebRequest = CType(WebRequest.Create(ParentFolderpath), FtpWebRequest)
ftpRequest.Credentials = New NetworkCredential(UserId, Password)
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory
Dim response As FtpWebResponse = CType(ftpRequest.GetResponse(), FtpWebResponse)
Dim streamReader As StreamReader = New StreamReader(response.GetResponseStream())
Dim directories As List(Of String) = New List(Of String)()
Dim line As String = streamReader.ReadLine()
While Not String.IsNullOrEmpty(line)
directories.Add(line)
line = streamReader.ReadLine()
End While
streamReader.Close()
Return directories
Catch ex As Exception
Return Nothing
End Try
End Function
As noted, it just returns a list for a given folder.
Next up, the routine to add to the treeview.
Sub PopulateTreeViewFiles(fRoot As String, dtParent As List(Of String), parentId As String, treeNode As TreeNode)
For Each sFile As String In dtParent
Dim sFileOnly As String = Replace(sFile, parentId, "")
Dim child As New TreeNode() With {
.Text = Replace(sFileOnly, "/", ""),
.Value = fRoot + sFileOnly
}
If InStr(sFileOnly, ".") <> 0 Then
child.ShowCheckBox() = True ' is a file - no expand
Else
child.PopulateOnDemand = True ' is folder - allow expand
End If
If parentId = "" Then
TreeView1.Nodes.Add(child) ' empty tree - add to base tree
Else
treeNode.ChildNodes.Add(child) ' user clicking on a node
End If
Next
End Sub
And that's it!!
The resulting screen looks like this:
So now you have a treeview based on FTP.
Note that each file does have a check box, so you can select as many files as you want, and then use the selected collection of the tree view.
So, not a lot of code, but the treeview is "dynamic". Note that we could fill the WHOLE treeview at the start (just move the ondemand code routine to the main routine), but as noted, this can slow things down a lot. This way, we ONLY pull + populate the starting folder, so it should work quite fast.
I don't have this in c#, but the above is simple enough You could send the above routines though a vb to c# converter, but the code is not complex, and is quite "basic". And the FTP code could be perhaps replaced with your own.

Move sub-chapters to the next page, if they are displaying at the end of a page (using openXML)

I´m creating a word document with openXML. This file includes several pages and chapters. Chapters of level 1 are automatically placed on a new page using
...new Break() { Type = BreakValues.Page });
. Now I would like to write a logic that moves sub-chapters to the next page, if they are at the end of a page and no content is following them (on this page).
Short: I´m looking for a way to minimize postediting on my newly created word document.

creating link to sub process in visio using c# or vba

Hi i am creating visio shapes programatically using c#.
In visio am creating composite diagrams ( sub - process ) using the below code.
Visio.Shape ParentShape = myShape;
ParentShape.CreateSubProcess(); //it will create a sub diagram for the shape
using this am creating subprocess(composite) diagram for the shape.
But now i need to link a sub process diagram to one or more parent shapes.
In Visio it can be simply done by clicking Link to SubProcess option.
But i want to acheive it in visio API..Is it possible to acheive it ..??
Question is:
How to assign a page to multiple shapes as sub-process in API .?
For linking a single page to multiple shape sub-process is done by adding the page name as hyperlink for that shapes , to which we need sub-process to be created.
Visio.Hyperlink vsoHyperlink = ParentShape.AddHyperlink();
vsoHyperlink.SubAddress = PageName;
ParentShape - the shape for which the sup-process (or ) composite to be created.
PageName- the name of the page or diagram in visio, which needs to be treated as sup-process (or ) composite

Get Frame Source from WebBrowser Control

I wrote up a function to save sites source as my WebBrowser control navigates around. I cant save only the WebBrowser.DocumentText as that leaves out all frame content.
The issue I'm having now is accessing the frame content - I cant find which method/property contains it.
The following works with a simple WebBrowser control, simply put saveWebsite(FilePath, WebBrowser1) in the DocumentCompleted event.
Ive done this in VB.NET but am familiar with C#, so C# solutions good too
Public Sub saveWebsite(ByVal sDirectory As String, ByVal oBrowser As WebBrowser)
File.WriteAllText(sDirectory & "index.htm", oBrowser.DocumentText)
'Now write a file for each frame - putting each file in its relative path'
For Each oFrame As HtmlWindow In oBrowser.Document.Window.Frames
oFI = New FileInfo(sDirectory & oBrowser.Url.MakeRelativeUri(oFrame.Url).ToString)
oFI.Directory.Create()
'ISSUE: This is the issue, unlike with oBrowser, there is no DocumentText property for oFrame.'
'ISSUE: Ive tried several things like Body.InnerText/Html, Body.OuterText/HTML, etc.'
File.WriteAllText(oFI.ToString, oFrame.WindowFrameElement.InnerText )
Next oFrame
End Sub
After more experimenting, I just found a solution. However its dirty and I dont particularly like it.
Switching the last/issue line from oFrame.WindowFrameElement.InnerText to oFrame.Document.All.Item(0).OuterHtml seems to do the trick sometimes. This wont do anything about nested frames, but Im not really worried about that.
Anywho, if anyone has a cleaner solution to the above, please let me know. (Or even a more effective/efficient way of "saving all").
Edit: The following seems to work a bit better, but still not great. (I had a webpage that started with <% VBSCRIPT %> and thats all that got saved) oFrame.Document.GetElementsByTagName("html").Item(0).OuterHtml
I was also facing simlar problem, I wanted to acess all the text contend within a Frame in a page. Below code worked for me
Dim frame = WebBrowser1.Document.Window.Frames(0) //Replace 0 with frame id if needed
Dim innderdiv= frame.Document.GetElementById("divContentLower")
Dim contents = innderdiv.InnerText
MsgBox(contents )
Here divContentLover is the id of an immediate child div within the frame. So the code returns its contents

How to change slide layout programmatically in PowerPoint?

I need to change a slide's layout programmaticaly with C# (Add-In Express 2009 for Office and .NET is used). If the new layout is a predefined one then everything is fine, but not if I need to set a custom layout as a new one (without slide recreating). Unfortunately, I didn't find any information on how to do it, PowerPoint object model reference documentation didn't answer me as well. There is just the ability to create a new slide that uses custom layout.
I've done an experiment and have ensured that the Slide object stayed being the same while I have been changing layout both predefined and custom ones. I don't want to create a new slide when I need just switch the layout.
Is it possible at all? Please help me to find a way of doing it.
The only way it will work is if your custom layout is actually used in the deck first. Then you simply take that layout and apply it to the slide you want. You could programatically create a new slide with your custom layout, use it's layout to apply to another slide and then delete that new slide you had created. Here's code to apply the custom layout (note that my ap.Slides(2) is a Custom Layout)
Sub ChangeLayout()
Dim ap As Presentation
Set ap = ActivePresentation
Dim slide1 As Slide
Set slide1 = ap.Slides(1)
Dim customLayout As PpSlideLayout
customLayout = ap.Slides(2).Layout
slide1.Layout = ly
End Sub
You could do that, but it's really not recommended. Also, creating a new slide this way and applying the layout is prone to errors. In the following code snippet you can see how to retrieve a layout by name from the master....
private PowerPoint.CustomLayout DpGetCustomLayout(
PowerPoint.Presentation ppPresentation, string myLayout)
{
//
// Given a custom layout name, find the layout in the master slide and return it
// Return null if not found
//
PowerPoint.CustomLayout ppCustomLayout = null;
for (int i = 0; i < ppPresentation.SlideMaster.CustomLayouts.Count; i++)
{
if (ppPresentation.SlideMaster.CustomLayouts[i + 1].Name == myLayout)
ppCustomLayout = ppPresentation.SlideMaster.CustomLayouts[i + 1];
}
return ppCustomLayout;
}
then you can assign it to the slide as you saw above. However, if the layouts are incompatible, then results may be unpredictable. I assume that the slides are at least relatively the same. You should try to create a new slide and copy the content over to avoid being hostage to changes in the underlying theme or template.
See code descriptions for more on this.

Categories