I started looking at the dropthings portal and I don't understand how the content within the widget gets loaded. My understanding is that the header is in an Updatepanel and the body of the widget is in an UpdatePanel with a ASP Panel in it. When the page loads, the ASP Panels of all the widgets load first before loading the User controls within the panels.
Can someone explain how this happens and point me to the code where this is setup?
Any help is appreciated
I'm using version 2.7.5 (released Jan 11), so this might be a bit newer.
Each widget is a user control, and is hosted in a WidgetContainer.ascx. The WidgetContainer provides all the common functions like the title renaming, positioning, expand/collapse, editing, etc. The source file is in the root "dropthings" folder. Looking at the Init method, we can see where the UserControl instantiated & added to the page:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
var widget = LoadControl(this.WidgetInstance.Widget.Url); //Here's the magic
widget.ID = "Widget" + this.WidgetInstance.Id.ToString();
WidgetBodyPanel.Controls.Add(widget);
_WidgetRef = widget as IWidget;
if (_WidgetRef != null) _WidgetRef.Init(this);
}
So, first the WidgetContainer is added to the control tree for each Widget configured. Then as each container is initialized, it creates then adds the specific UserControl to the page. When
WidgetBodyPanel.Controls.Add(widget);
is called, it will initialize (OnInit) the specific widget. From there the contents of the widget are in it's own hands.
Related
Description
When using custom renderer for the content view. It throws "Element is already the child of another element" while converting the content of the content view to the content presenter using the content control.
Steps to Reproduce
Run the attached sample.
Navigate to the sub page and navigate back.
Content view gets hidden and page not navigated back properly.
Exception gets thrown in the on element changed method of custom renderer.
Expected Behavior
Page should be navigated back properly with the content view as like the second time.
Actual Behavior
In first time page is not navigated back properly and also content view gets disappear.
Screenshots
Actual Output
Expected Output
Workaround
Please check the below sample.
CustomControl.zip
Can anyone help me with this?
Element is already the child of another element"
The problem is your CustomView has been referenced by previous view, when you navigation back, the navigation create new ContentPage that want to use previous CustomView, but the previous CustomView has not be released. For solving this problem, you could set TitleViewProperty as null when page OnDisappearing.
protected override void OnDisappearing()
{
base.OnDisappearing();
SetValue(NavigationPage.TitleViewProperty, null);
}
Update
Please set TitleViewProperty in OnAppearing method like the following.
protected override void OnAppearing()
{
base.OnAppearing();
SetValue(NavigationPage.TitleViewProperty, new NavigationView());
}
protected override void OnDisappearing()
{
base.OnDisappearing();
SetValue(NavigationPage.TitleViewProperty, null);
}
Is there a way to detect which node is being rendered when the user selects a link within the pages detail app and only the iframe changes? If just the the iframe is changing I need a mechanism that can call the parent page and send the path of the node that is being rendered in the iframe. We run Magnolia EE 5.6.11.
My issue is that I have a ValueChangeListener in a ComboBox that I use as a versionSelector in a PageBar extension in the pages detail app.
// Create a selection component;
private ComboBox versionSelector = new ComboBox();
private Listener listener;
private boolean isSettingValue;
public VersionSelectorViewImpl(){
construct();
}
private void construct() {
versionSelector.setVisible(false);
versionSelector.setSizeUndefined();
versionSelector.setImmediate(true);
versionSelector.setNullSelectionAllowed(false);
versionSelector.setTextInputAllowed(false);
//setup listener for the selected item
versionSelector.addValueChangeListener(new Property.ValueChangeListener() {
#Override
public void valueChange(Property.ValueChangeEvent event) {
if (listener != null) {
listener.versionSelected((Object) event.getProperty().getValue());
}
}
});
}
The implementation is similar to the LanguageSelector or VariantSelector. When someone activates a hyperlink in the page template the iframe changes and the valueChange method retrieves the wrong value (ie. the event is from the previous page).
When someone activates a link, the PagesEditorSubApp#updateNodePath calls the updateLocationDependentComponents which calls the PageBar.onLocationUpdate. This calls in our case the VersionSelector#setCurrentVersion method. At this point I would need to reload the page detail subapp so that the listener is correctly set to the new page. I tried using the pageEditorPresenter.refresh() method in the setCurrentVersion method but it didn't do it.
In Magnolia 5.x you need to fire ContentChangeEvent to trigger the refresh (and hope that subapp you want to refresh listens to it, which in case of page detail subapp shouldn't be a problem).
Or, since you mention LanguageSelector, you can indeed try to call PageEditorPresenter directly as it does from info.magnolia.pages.app.editor.pagebar.languageselector.LanguageSelector#languageSelected, tho unless you need to modify something in the presenter (eg. locale in the example above), it seems rather unnecessary coupling of the code.
Once you are migrating your code to Magnolia 6.x and new UI framework, you have more convenient way of triggering notification of datasource change which all the views consuming data from given source listen to and facilitating refresh that way (as is shown eg in PasteComponentAction here.
I am trying to download information from a website and I have hit (yet another) brick wall in a long and tiresome journey to get something productive developed.
I have a program which uses WebBrowser to login to a site - with a valid username and password - therby allowing me to set up a legitimate connection to it and retrieve information (my own) from it.
From the initial page presented to me after login, I can use WebBrowser.Document.GetElementsByTagName("A") and WebBrowser.Document.GetElementById("Some Id") etc. to work my way around the website, and processing all the DocumentCompleted events returned until ... I arrive at a page which appears to have a TabControl embedded in it.
I need to be able to choose the middle Tab of this control, and retrieve the information it holds. When I access this information 'normally' (i.e. from IE and not from my WebBrowser program) I can click each of the three tabs and information duly appears - so its there, tantalisingly so ... but can I manupulate these Tabs from my program? I feel it should be possible, but I can't see how I can do it.
The problem manifests itself because when I am processing the page which has the Tab in it my code looks like this:
static void wb_TabPage(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser wb = (WebBrowser)sender;
HtmlElement element;
element = wb.Document.GetElementById("Bills"); // Find the "Bills" tab
element.InvokeMember("Click"); // Click the "Bills" tab
// Unhook THIS routine from DocumentCompleted delivery
wb.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(wb_TabPage);
// Hook up this routine - for the next 'Document Completed' delivery - which never arrives!
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_Bills);
return;
}
And that's the problem - no more Documents are ever 'Completed' for me to process, even after the InvokeMember("Click"). It seems for all the world that the Tabs are being updated inplace, and no amount of Refresh(ing) or Navigating or Event Handling will allow me to get to a place or in a position where I can get the data from them
Does anybody have any idea how I can do this? Does anybody know how to manipulate Tabs from WebBrowser? Thanks in advance if you do ...
Try using the findcontrol function on your page. You will likely need to drill into the tab control itself to find the tab page and the controls contained in it.
I would like to add custom right clicks to a number of spark list controls.
I have tried the following as an item renderer. (as per the flex 4 cook book).
Full Render code here http://pastebin.com/Kx8tJ1cY
When I right click on the Spark List I simply get the Adobe Default Context menu.
This is the same default behaviour I had before I added any code to this.
Could anyone tell me how to add right clicks to List Items in Flex 4.
Please and Thank you.
I found the problem/solution. You cant use context menus if there are Vboxes or Tab Navigators. Which is insane because it means I cant do relative layout properly or decent variable width design.
Quoted from: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/ContextMenu.html
For example, if a DataGrid control is a child of a TabNavigator or VBox container, the DataGrid control cannot have its own context menu.
Christopher Huyler posted something similar (source code available here). From the article:
Start out by grabbing the Javascript code from Google's code repository.
Step 1 – Setup custom context menu code
Create a new Flex project in Flex Builder. Copy rightclick.js and swfobject.js into the html-template folder of your project. From here, I had to make several changes…
I modified the RightClick.init() function to accept an object and container value as input. This allows me to pass in the name of the application as the object instead of having it be called the same thing every time.
I included rightclick.js and swfobject.js in the header of index.template.html.
I added a new div to the body called “flashcontent”.
I added an onload handler to the body tag to initialize RightClick
I replaced AC_FL_RunContent(…) with new SWFObject(…) making sure to maintain all template variables.
After making these changes, I verified that no right-click context menu appears in my application.
Step 2 – Listen for the rightClick event
Next I added a few lines to the main mxml file of my application to listen for the ExternalInterface event that will be dispatched when I right-click my appliction.
private function handleCreationComplete():void
{
ExternalInterface.addCallback("rightClick", handleRightClick);
}
private function handleRightClick():void
{
Alert.show("Right Click Success!");
}
Step 3 – Dispatch an event to the correct object
Getting the event to the main application is easy, but we actually want the appropriate child object to be notified when the right-click event occurs. Since I am not using any double-click events in my application I decided I would treat every right-click event like a double-click event. Users without a two button mouse (aka Mac users) can simply double-click to get the same menu while users with a two button mouse just have to right-click. Here is how I make sure the event is dispatched to the appropriate object.
private function handleRightClick():void
{
var objects:Array = systemManager.getObjectsUnderPoint(
new Point(mouseX,mouseY));
if (objects.length>0)
{
var object:Object = objects[objects.length-1];
var relatedObject:InteractiveObject;
if (object is InteractiveObject)
relatedObject = object as InteractiveObject;
else if (object.parent && object.parent is InteractiveObject)
relatedObject = object.parent;
var event:MouseEvent = new MouseEvent(
MouseEvent.DOUBLE_CLICK,true,false,mouseX,mouseY,
relatedObject);
object.dispatchEvent(event);
}
}
I hope this helps!
In my website I'm using the standard ASP.NET menu control. I already got so far as to write a custom control adapter to get rid of the rather tacky html output that is generated by the default control adapter.
One thing keeps buggering me though. Somehow ASP.NET is generating extra javascript that I don't want nor need for my menu controls, since I won't be using any of the dynamic features in the control. I replaced the control adapter, so it doesn't generate compatible HTML for that.
Anyone got an idea how I can prevent ASP.NET from generating the extra javascript for the menu control?
This problem cropped up for me after upgraded to ASP.net 4.0 with the installation of vs 2010. The fix is to either force the menu to render as a table or to turn off the new CSS/javascript "features" that 4.0 adds. Settings the menu's RenderingMode attribute to "Table" fixed this problem for me even though I use a Menu Adapter to render the control with lists.
<asp:Menu ID="mnuStuff" runat="server" RenderingMode="Table">
...
</asp:Menu>
You can do this site wide setting controlRenderingCompatibilityVersion to 3.5 in the web.config:
<system.web>
<pages controlRenderingCompatibilityVersion="3.5"/>
</system.web>
This will eliminate the rendering of inline javascript that asp injects in the base of the page.
If you prefer to stick with ASP.Net 4.0 control rendering you can create a custom menu (derived from System.Web.UI.WebControls.Menu) and replace the OnPreRender:
public class MyCustomMenu : Menu
{
protected override void OnPreRender(EventArgs e)
{
// Don't call base OnPreRender
//base.OnPreRender(e);
}
}
That did the trick.
An alternative way to get rid of the menu startup script is to call RegisterStartup script method before the Menu PreRender event, using the same script key, and outputting dummy (or empty) script.
This relies on internal implementation details of the Menu Type discovered using Reflector, so is somewhat fragile.
For example, a static class that looks something like:
static MenuHelper
{
private static Type _rendererType =
typeof(Menu).Assembly.GetType(
typeof(Menu).FullName + "+MenuRendererStandards"
);
public static void RemoveMenuScript(Menu menu)
{
string dummyScript = "<!-- Removed Menu Startup script -->";
string key = "_registerMenu_" + menu.ClientID;
ScriptManager.RegisterStartupScript(menu, _rendererType, key, dummyScript, false);
}
}
You then just need to make sure you call MenuHelper.RemoveMenuScript(menu) before the menu's PreRender event.
The OP is using an Adapter so Tim Santeford's answer is better in his situation. But if you want to render a static menu as a list without the startup code, and without the effort of writing an adapter, this might be an alternative.
<script type="text/javascript">
Sys.WebForms.Menu = "";
</script>
it works..
use it in aspx page
I just plan to ask about a similar question after 2 hours of search and have no luck.
What I want is to use the jquery superfish plugin as I want its animation for smooth looking. And with the ASP.NET generated javascript, the superfish just won't work.
And finally I try to set the ASP.NET Menu's control's attribute Enabled = false
and the outcoming source becomes this:
new Sys.WebForms.Menu({ element: 'mysitemeun', disappearAfter: 500, orientation: 'horizontal', tabIndex: 0, disabled: **true** });
After tracing the code, setting it disabled still have some style changes in the Menu but it will not add event to the MenuItem. And the superfish's animation works now.
if (!this.container.disabled) {
Sys.WebForms.Menu._domHelper.addEvent(this.element, 'mouseover', Sys.WebForms.MenuItem._onmouseover);
Sys.WebForms.Menu._domHelper.addEvent(this.element, 'mouseout', Sys.WebForms.MenuItem._onmouseout);
}