Disposing of Flowdocument Page after rendering - pagination

//Create a User Control with a TextBlock
TextBlock textBlock = new TextBlock();
textBlock.Text = "Helo";
UserControl userCOntrol = new UserControl();
userCOntrol.Content = textBlock;
//Add the UserControl to a Table
table.RowGroups[0].Rows[0].Cells[0].Blocks.Add(new Paragraph(new InlineUIContainer(userCOntrol as UIElement)));
//Add the table to a FlowDocument
FlowDocument flowDocument = new FlowDocument();
flowDocument.Blocks.Add(table);
//Fetch the Visual representation of the page.
DocumentPage page = ((IDocumentPaginatorSource)flowDocument).DocumentPaginator.GetPage(0);
//Extract the Visual from the page and add to a Fixed Page
FixedPage fixedPage = new FixedPage();
ContainerVisual container = new ContainerVisual();
container.Children.Add(page.Visual);
DrawingCanvas canvas= new DrawingCanvas();
canvas.AddVisual(container);
fixedPage.Children.Add(canvas);
//now write the FixedPage to an XPS file
using (XpsDocument xpsDoc = new XpsDocument("c:\\x.xps", FileAccess.ReadWrite))
{
XpsDocumentWriter xpsDw = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
xpsDw.Write(kj);
}
The above piece of code releases nothing. Once the flowdocument is paginated and Visual representation of the page fetched, the contents of the flowdocument are refernced by the Visual. so neither Visual gets disposed nor the contents of flowdocument.
The above piece of code when executed continuously raised out of memory.
Does anyone know how to release the memory held by all these resources?
Thanks in advance.

Related

Create Property Sheet in Frame Window

I am using an MDI application. I want to create a property sheet inside Frame Window area as shown by arrow in image below:
I have seen examples where we can use ShowWindow() function after creating property sheet but it creates property sheet which is not embedded in frame window.
Can we create propertysheet on frame window only like other controls as static box etc?
If you need to embed a resizable property sheet to the view, please take a look at BCGSoft size(http://www.bcgsoft.com) - the latest BCGControlBar from version shows how to do it:
http://www.bcgsoft.com/images/resizableform220.jpg
If you simply need a tabbed MDI windows, just create a Visual Studio-like application in MFC AppWizard (VS 2008 or later).
Hope, this helps.
Rob
Adding CMultiDocTemplate instances solved my problem. Here is code snippet. This is part of ProjectName.cpp file:
BOOL CEmuDiagnosticsClientApp::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinAppEx::InitInstance();
// Initialize OLE libraries
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
//Added new code
{
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_STRING_LOGGINGWINDOW,
RUNTIME_CLASS(CEmuDiagnosticsClientDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CLoggingWindow));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
}
//End: Added new code
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(4); // Load standard INI file options (including MRU)
InitContextMenuManager();
InitKeyboardManager();
InitTooltipManager();
CMFCToolTipInfo ttParams;
ttParams.m_bVislManagerTheme = TRUE;
theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_STRING_SIGNALWINDOW,
RUNTIME_CLASS(CEmuDiagnosticsClientDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CSignalWindow)); //Changed Code
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
// create main MDI Frame window
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
{
delete pMainFrame;
return FALSE;
}
m_pMainWnd = pMainFrame;
// call DragAcceptFiles only if there's a suffix
// In an MDI app, this should occur immediately after setting m_pMainWnd
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line. Will return FALSE if
// app was launched with /RegServer, /Register, /Unregserver or /Unregister.
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The main window has been initialized, so show and update it
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
return TRUE;
}
In //Added New code section, created a new CMultiDocTemplate instance. CLoggingWindow is the class which I wanted to display in frame window.
Another class CSignalWindow I also wanted to display which is modified in //changed code area.
Things to remember:
-Dialog which you want to display must be derived from CFormView, not CDialog.
-Changed dialog property: Border -> None, Style -> Child and all other properties to false.

CommandBarButton on Context Menu doesn't work after ElementHost becomes visible

I have a CommandBarPopup on a the context menu in excel that contains three CommandBarButtons, one of those buttons opens a web page, the other two open a custom task pane.
If I make the custom task pane containing an element host which hosts a WPF user control visible then the any of the CommandBarButtons I have added will stop working.
Even if I close the custom task pane it will still not work.
If I do the same with a custom task pane container a web browser it seems to work fine.
Here is the code we are using
private void InitializeComponent()
{
this.elementHost1 = new System.Windows.Forms.Integration.ElementHost();
this.myView = new MyView();
this.SuspendLayout();
//
// elementHost1
//
this.elementHost1.Dock = System.Windows.Forms.DockStyle.Fill;
this.elementHost1.Location = new System.Drawing.Point(0, 0);
this.elementHost1.Name = "elementHost1";
this.elementHost1.Size = new System.Drawing.Size(780, 560);
this.elementHost1.TabIndex = 0;
this.elementHost1.Text = "elementHost1";
this.elementHost1.Child = this.myView;
//
// MyTaskPane
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.elementHost1);
this.Name = "MyTaskPane";
this.Size = new System.Drawing.Size(780, 560);
this.ResumeLayout(false);
}
So the answer was that the CommandBarButtons were being disposed once the variable scope ended which was surprising as I would have assumed they would be attached to the excel application object. Also looking at the excel commandbar, I could see the buttons there but clicking on them resulted in the click event not triggering.
Anyway I stored them in a class variable and it worked again.

Trying to Use LoadMoreElement in Monotouch.Dialog

I am using Monotouch to write an Ipad app. The app uses tables to browse down through a directory tree and then select a file. I have used Monotouch.Dialog to browse the directories and I set up the directory tables as the app starts.However there are too many files to set up in a table as the app starts and so I want to set up the 'file table' as the file is selected from the lowest level directory table. I am trying to use LoadMoreElement to do this but I cannot make it work or find any examples online. I have coded the 'Elements API Walkthrough' in the Xamarin tutorial at:- http://docs.xamarin.com/ios/tutorials/MonoTouch.Dialog
I then add a new section to the code:-
_addButton.Clicked += (sender, e) => {
++n;
var task = new Task{Name = "task " + n, DueDate = DateTime.Now};
var taskElement = new RootElement (task.Name){
new Section () {
new EntryElement (task.Name,
"Enter task description", task.Description)
},
new Section () {
new DateElement ("Due Date", task.DueDate)
},
new Section()
{
new LoadMoreElement("Passive","Active",
delegate {MyAction();})
}
};
_rootElement [0].Add (taskElement);
Where MyAction is:-
public void MyAction()
{
Console.WriteLine ("we have been actioned");
}
The problem is that MyAction is triggered and Console.Writeline writes the message but the table stays in the active state and never returns to passive. the documentation says:-
Once your code in the NSAction is finished, the UIActivity indicator stops animating and the normal caption is displayed again.
What am I missing?
Ian
You need to set the "Animating" property in the element to false.
Like this:
LoadMoreElement loadMore = null;
loadMore = new LoadMoreElement (
"Passive", "Active",
delegate {loadMore.Animating = false;});
Where did you see any documentation that says that the animation stops when the delegate stops running? If that is documented anywhere, that is wrong.

qooxdoo virtual tree as menu

I have a function, which creates layout with widgets. The problem is what one of the widget is virtual tree (on left side of layout) and the second widget on the right side depends on clicked row on left side. Virtual tree works like menu, which should return value of row name to the right widget and recreate it on right side with provided data. However currently it is not recreating, but adding a new widget to the old one. How to recreate widget on the right side not adding it to the existing one (interface is similar to qooxdoo demobrowser view with tests)?
_createLayout : function()
{
// Create main layout
var dockLayout = new qx.ui.layout.Dock();
var dockLayoutComposite = new qx.ui.container.Composite(dockLayout);
this.getRoot().add(dockLayoutComposite, {edge:0});
// Create header
this.__header = new bank.view.Header();
dockLayoutComposite.add(this.__header, {edge: "north"});
// Create toolbar
this.__toolBarView = new bank.view.ToolBar(this);
dockLayoutComposite.add(this.__toolBarView, {edge: "north"});
// Create the tree view, which should create dockLayout below, when user clicks with Row value
dockLayoutComposite.add(this.getTreeView(), {edge: "west"});
// This layout should be created and recreated with clicked row value
dockLayoutComposite.add(bank.InvoiceListBuilder.createList("Tree_returned_value"), {edge: "center"});
},
getTreeView : function()
{
var hBox = new qx.ui.container.Composite(new qx.ui.layout.HBox(20));
var tree = new qx.ui.treevirtual.TreeVirtual("Tree");
tree.setColumnWidth(0, 170);
tree.setAlwaysShowOpenCloseSymbol(true);
var dataModel = tree.getDataModel();
var te2 = dataModel.addBranch(null, "Folders", true);
dataModel.addBranch(te2, "Incoming", false);
dataModel.addBranch(te2, "Outgoing", false);
dataModel.addBranch(te2, "Drafts", false);
dataModel.setData();
hBox.add(tree);
var foldercontent = bank.InvoiceListBuilder.createList("incoming");
tree.addListener("changeSelection",
function(e)
{
// this function should return row value to function: bank.InvoiceListBuilder.createList("Tree_returned_value") and create/recreate dockLayout with newly created widget from bank.InvoiceListBuilder.createList function
});
return hBox;
},
you are using a old virtual tree implementation (qx.ui.treevirtual.TreeVirtual), I would suggest to use the qx.ui.tree.VirtualTree implementation.
The next step is to use something like a controller for your view, which listen to the selection and creates widgets when the selection changed. The controller should know the container for adding widgets.
When your left side is just a list. You can also use the virtual list (qx.ui.list.List) and use a set of the tree model.
Cheers,
Chris

Can I programmatically replace one webpart with another in Sharepoint?

Edit: This is a decade old so very likely not to be relevant to anyone, if google has brought you here I would be sceptical of the content against more modern frameworks!
We have a sharepoint website that has been quite heavily developed with content using the out of the box content editor webpart. This is a bit rubbish when it comes to using any other browser than IE.
We have in mind to update to the free Telerik content editor, however we would like to save ourselves a large amount of copy and pasting, and clicking and selecting to swap the web parts over.
There seems to be no official upgrade path but it seems to me that it must be possible to use the power of code (tm) to grab the content of the original webpart, new up a telerik webopart and put the content into the new webpart... then delete the old original web part.
Has anyone done this sort of thing? How is it best to lay out the code and actually run the code that will do the swap (if it is possible). A fresh webpart with a "Do Swap" button on? or something more sophisticated?
I also would need to walk through every page and subsite (and page in subsite) and look at every web part. Is there a best practice way of doing this?
I would write a console application for this.
Open the root Web and iterate through its sub webs.
Do the work needed for each page, by opening the WebPartManager.
Here are some pseudo code to get you started.
string SourceUrl = "http://ThisWeb";
using (SPSite sourceSite = new SPSite(SourceURL))
{
using (SPWeb sourceWeb = sourceSite.OpenWeb(SourceURL))
{
IterateSubWebsProd(sourceWeb):
}
}
private void IterateSubWebsProd(SPWeb sourceWeb)
{
// This is the migration function
DoThingyWithThisWeb(sourceWeb);
foreach (SPWeb subWeb in sourceWeb.Webs)
{
IterateSubWebsProd(subWeb);
subWeb.Dispose();
}
}
private void DoThingyWithThisWeb(SPWeb sourceWeb)
{
PublishingPage currentPage = null;
string currentPageName = "<something>";
// Find the pages that you want to modify, with a CAML query for example
SPQuery query = new SPQuery();
query.Query = string.Format("" +
"<Where>" +
"<Eq>" +
"<FieldRef Name='FileLeafRef' />" +
"<Value Type='File'>{0}</Value>" +
"</Eq>" +
"</Where>" +
"", currentPageName);
// This codesnippet is from a Publishing web example
PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(sourceWeb);
PublishingPageCollection pageColl = publishingWeb.GetPublishingPages(query);
if (pageColl.Count > 0)
{
currentPage = pageColl[0];
}
using (SPLimitedWebPartManager wpMan = currentPage.ListItem.File.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))
{
foreach (WebPart wp in wpMan.WebParts)
{
if (wp.GetType().Equals(typeof(Microsoft.SharePoint.WebPartPages.ContentEditorWebPart)))
{
Microsoft.SharePoint.WebPartPages.ContentEditorWebPart thisWebPart = wp as Microsoft.SharePoint.WebPartPages.ContentEditorWebPart;
// This is just dummy code, here you will do your content migration
XmlDocument xmlDoc = new XmlDocument();
XmlElement xmlElement = xmlDoc.CreateElement("RootElement");
xmlElement.InnerText = sourceItem[SourceField].ToString();
thisWebPart.Content = xmlElement;
wpMan.SaveChanges(thisWebPart);
}
}
}
}
I'm not 100% certain on this, but if your content is saved into a list as individual fields, could you not point the Telerik controls at where that content is saved? This may cause Telerik controls to freak out a bit on the first edit of that content, but they should be ok to re-format the content and recover.

Resources