I am using GeckoFx in my windows form app. When I select a feature in Gecko it should fill the attributes attr1 and attr2 of 'selectedfeature' class based on geojson file that loaded to html file. I test that html file and when clicking a feature this attributes will be filled (with javascript code).
<div class="selectedfeature" attr1="attr1" attr2="attr2"></div>
and when I want to retrieve these attributes from Gecko in 'geckoWebBrowser_DomClick' event, this event is raised first and so attributes attr1 and attr2 will be empty.
I used another events but nothing happened.
Any suggestion?
I moved the contents of 'geckoWebBrowser_DomClick' to another method 'DomClicked()' and this method called again when I get a property (SelectedFeature) that its value should be filled with attr1 or attr2.
private void geckoWebBrowser_DomClick(object sender, Gecko.DomMouseEventArgs e)
{
DomClicked();
}
private string _selectedFeature;
public string SelectedFeature
{
get
{
GBDomClick();
return _selectedFeature;
}
private set { _selectedFeature= value; }
}
By this (second called of DomClicked()),
<div class="selectedfeature" attr1="attr1" attr2="attr2"></div>
are filled with click event of javascript code. But in the first call:
<div class="selectedfeature" attr1="" attr2=""></div>
click event of javascript code does not execute.
Related
WebBrowser Control seems to re-arrange attributes within HTML tags when setting webBrowser1.DocumentText..
I'm wondering if there is some kind of render mode or Document Encoding that I am missing. My problem can be seen by simply adding a RichTextBoxControl (txt_htmlBody) and a WebBrowser control (webBrowser1) to a windows form.
Add webBrowser1 WebBrowser Control, and add an event handler to; webBrowser1_DocumentCompleted
I used this to add my mouse click event to the web browser control.
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// Attach an event to handle mouse clicks on the web browser
this.webBrowser1.Document.Body.MouseDown += new HtmlElementEventHandler(Body_MouseDown);
}
In the mouse click event, we get which element was clicked on like so;
private void Body_MouseDown(Object sender, HtmlElementEventArgs e)
{
// Get the clicked HTML element
HtmlElement elem = webBrowser1.Document.GetElementFromPoint(e.ClientMousePosition);
if (elem != null)
{
highLightElement(elem);
}
}
private void highLightElement(HtmlElement elem)
{
int len = this.txt_htmlBody.TextLength;
int index = 0;
string textToSearch = this.txt_htmlBody.Text.ToLower(); // convert everything in the text box to lower so we know we dont have a case sensitive issues
string textToFind = elem.OuterHtml.ToLower();
int lastIndex = textToSearch.LastIndexOf(textToFind);
// We cant find the text, because webbrowser control has re-arranged attributes in the <img> tag
// Whats rendered by web browser: "<img border=0 alt=\"\" src=\"images/promo-green2_01_04.jpg\" width=393 height=30>"
// What was passed to web browser from textbox: <img src="images/PROMO-GREEN2_01_04.jpg" width="393" height="30" border="0" alt=""/>
// As you can see, I will never be able to find my data in the source because the webBrowser has changed it
}
Add txt_htmlBody RichTextBox to the form, and set a TextChanged of the RichTextBox event to set the WebBrowser1.DocumentText as the RichTextBox (txt_htmlBody) text changed.
private void txt_htmlBody_TextChanged(object sender, EventArgs e)
{
try
{
webBrowser1.DocumentText = txt_htmlBody.Text.Replace("\n", String.Empty);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
When you run your program, copy the below example HTML into txt_htmlBody, and click the Image on the right and debug highLightElement. You will see by my coments why I can not find the specified text in my search string, because WebBrowser control re-arranges the attributes.
<img src="images/PROMO-GREEN2_01_04.jpg" width="393" height="30" border="0" alt=""/>
Does anyone know how to make WebBrowser control render my HTML as-is?
Thank you for your time.
You cannot expect the processed HTML to be 1:1 the same as the original source, when you obtain it back via element.OuterHtml. It's almost never the same, regardless of the rendering mode.
However, despite the attributes may have got rearranged, their names and values are still the same, so you'd just need to improve your search logic (e.g., by walking the DOM three or simply enumerating elements via HtmlDocument.All and checking their attributes via HtmlElement.GetAttribute).
I create a user control and add a textbox to it. In my windows form I add the user control i created and add a textbox and a button. How to copy the text I input from the textbox of Form to textbox of Usercontrol and vice versa. Something like
usercontrol.textBox1.text = textBox1.text
You could add to your User Control code a public property that delegates into the TextBox's Text property:
public string MyTxtBoxValue { get { return this.txtBox.Text; } }
And you could also have a setter to that, of course, if needed.
What you don't want to do, however, is exposing the whole TextBox by making it public. That is flawed.
From Form to Usercontrol
Form Code
public string ID
{
get { return textBox1.Text; }
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
userControl11.ID = ID;
}
Usercontrol Code
public string ID
{
set { textBox1.Text = value; }
}
There are multiple ways to access your user control text box data. One way to accomplish this would be to expose the text box on the user control at a scope that can be accessed via the form it's loaded on. Another way would be raising an event on the button click of the user control and subscribing to it on the parent form.
Although some stuff are inherited when creating a custom user control, for the most part you have to define your own properties. (like text value, etc..)
I would take a look at this:
http://msdn.microsoft.com/en-us/library/6hws6h2t.aspx
good luck!
I have a button control. On click of this button I need to add a Link Button dynamically. The Link Button needs an event handler. Hence the dynamic Link button is first added in the Page_Load and cleared and added again in the button click handler. Please read Dynamic Control’s Event Handler’s Working for understanding the business requirement for this.
I have read On postback, how can I check which control cause postback in Page_Init event for identifying the control that caused the postback (inside Page_Load). But it is not working for my scenario.
What change need to be done to confirm whether the postback was caused by link button (inside Page_Load)?
Note: Refer the following for another scenario where it is inevitable https://codereview.stackexchange.com/questions/20510/custom-paging-in-asp-net-web-application
Note 1: I need to get the postback control ID as the first step inside if (Page.IsPostBack). I need to add the dynamic link buttons control only if it is a postback from the button or the link button. There will be other controls that causes postback. For such postbacks we should not execute this code.
Note 2: I am getting empty string for Request["__EVENTARGUMENT"] in the Page_Load
Related Question: By what event, the dynamic controls will be available in the Page (for using in FindControl). #Tung says - "Your GetPostBackControlId method is properly getting the name of the control that caused the postback, but it is unable to find a control with that id through page.FindControl because the linkbutton has not been created yet, and so page does not know of its existence. "
ASPX
<%# Page Language="C#" AutoEventWireup="true" CodeFile="PostbackTest.aspx.cs" Inherits="PostbackTest"
MasterPageFile="~/TestMasterPage.master" %>
<asp:Content ID="myContent" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div id="holder" runat="server">
</div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="TestClick" />
</asp:Content>
CODE BEHIND
public partial class PostbackTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(Page.IsPostBack)
{
string IDValue = GetPostBackControlId(this.Page);
int x = 0;
holder.Controls.Clear();
LinkButton lnkDynamic = new LinkButton();
lnkDynamic.Click += new EventHandler(LinkClick);
lnkDynamic.ID = "lnkDynamic123";
lnkDynamic.Text = "lnkDynamic123";
holder.Controls.Add(lnkDynamic);
}
}
protected void TestClick(object sender, EventArgs e)
{
holder.Controls.Clear();
LinkButton lnkDynamic = new LinkButton();
lnkDynamic.Click += new EventHandler(LinkClick);
lnkDynamic.ID = "lnkDynamic123";
lnkDynamic.Text = "lnkDynamic123";
holder.Controls.Add(lnkDynamic);
}
protected void LinkClick(object sender, EventArgs e)
{
}
public static string GetPostBackControlId(Page page)
{
if (!page.IsPostBack)
{
return string.Empty;
}
Control control = null;
// First check the "__EVENTTARGET" for controls with "_doPostBack" function
string controlName = page.Request.Params["__EVENTTARGET"];
if (!String.IsNullOrEmpty(controlName))
{
control = page.FindControl(controlName);
}
else
{
// if __EVENTTARGET is null, the control is a button type
string controlId;
Control foundControl;
foreach (string ctl in page.Request.Form)
{
// Handle ImageButton they having an additional "quasi-property" in their Id which identifies mouse x and y coordinates
if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
{
controlId = ctl.Substring(0, ctl.Length - 2);
foundControl = page.FindControl(controlId);
}
else
{
foundControl = page.FindControl(ctl);
}
if (!(foundControl is Button || foundControl is ImageButton)) continue;
control = foundControl;
break;
}
}
return control == null ? String.Empty : control.ID;
}
}
REFERENCE
On postback, how can I check which control cause postback in Page_Init event
Dynamic Control’s Event Handler’s Working
Understanding the JavaScript __doPostBack Function
Access JavaScript variables on PostBack using ASP.NET Code
How does ASP.NET know which event to fire during a postback?
how to remove 'name' attribute from server controls?
How to use __doPostBack()
A postback in asp.net is done by the java script function __doPostback(source, parameter)
so in your case it would be
__doPostback("lnkDynamic123","") something like this
So in the code behind do the following
var btnTrigger = Request["__EVENTTARGET"];
if(btnTrigger=="lnkDynamic123")
{
}
--- this would tell that it is your linkbutton that causes the postback
You can move the call to the GetPostBackControlId method after the LinkButton has been added to the page:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
holder.Controls.Clear();
LinkButton lnkDynamic = new LinkButton();
lnkDynamic.Click += new EventHandler(LinkClick);
lnkDynamic.ID = "lnkDynamic123";
lnkDynamic.Text = "lnkDynamic123";
holder.Controls.Add(lnkDynamic);
string IDValue = GetPostBackControlId(this.Page);
if (IDValue == lnkDynamic.ID)
LinkClick(lnkDynamic, new EventArgs());
}
}
Calling the click event handler here also more closely mimics the standard ASP.NET Page Life Cycle, where Postback event handling occurs after the Load event.
Edit:
If the control ID must be determined before the LinkButtons are created, you can create a naming scheme for the link button IDs, e.g. lnkDynamic_1, lnkDynamic_2 etc.
Request["__EVENTTARGET"] will then contain the auto-generated control ID such as “ctl00$mc$lnkDynamic_1”, which you can use to identify which LinkButton caused the postback.
If You're getting the post back control id correctly but FindControl returns nothing, then it's probably because You're using a master page. Basically, someControl.FindControl(id) searches through controls that are in someControl.NamingContainer naming container. But in Your case, the Button1 control is in the ContentPlaceHolder1, which is a naming container, and not directly in the Page naming container, so You won't find it by invoking Page.FindControl. If You can't predict in which naming container the control You're looking for is going to be (e.g. post back can be caused by two different buttons from two different content placeholders), then You can write an extension that'll search for a control recursively, like so:
public static class Extensions
{
public static Control FindControlRecursively(this Control control, string id)
{
if (control.ID == id)
return control;
Control result = default(Control);
foreach (Control child in control.Controls)
{
result = child.FindControlRecursively(id);
if (result != default(Control)) break;
}
return result;
}
}
Use it with caution though, because this method will return the first control that it finds with the specified id (and You can have multiple controls with the same id - but they should be in different naming containers; naming containers are meant to differentiate between controls with same ids, just as namespaces are meant to differentiate between classes with same names).
Alternatively, You could try to use FindControl(string id, int pathOffset) overload, but I think it's pretty tricky.
Also, check this question out.
First approach (wouldn't recommend but it's more flexible)
One completely different approach - although I don't really feel like I should promote it - is to add a hidden field to the form.
The value of this hidden field might be something like false by default.
In case of clicking one of the dynamic buttons which should cause the dynamic controls to be added again, you can simply change the hidden fields value to true on client side before performing the postback (eventually you want/have to modify the client side onclick handler to make this happen).
Of course it would be possible to store more information in such a field, like the controls id and the argument (but you can get those values as described in the other answers). No naming schema would be required in this case.
This hidden field could be "static". So it would be accessible in code behind all time. Anyhow, you might want to implement something to make sure that nobody is playing around with its values and fakes a callback which looks like it originated from one of these dynamic links.
However, this whole approach just helps you getting the id of the control. Until you create the control again, you won't be able to get the instance through NamingContainer.FindControl (as mentioned in the other answers already ;)). And in case you create it, you don't need to find it anymore.
Second approach (might not be suitable due to its contraints)
If you want to do it the clean way, you need to create your controls OnLoad, no matter if something was clicked or not. Additionally, the dynamic controls ID has to be the same as the one you sent to the client in the first place. You subscribe to its Click or Command event and set its visibility to false. Inside the click event handler, you set the senders visibility to true again. This implies, that you don't care if that link is created but instead just don't want to send it to the client. The example below only works for a single link of course (but you could easily modify it to cover a whole group of links).
public void Page_Load(object sender, EventArgs e)
{
LinkButton dynamicButton = new LinkButton();
dynamicButton.ID = "linkDynamic123";
// this id needs to be the same as it was when you
// first sent the page containing the dynamic link to the client
dynamicButton.Click += DynamicButton_Click;
dynamicButton.Visible = false;
Controls.Add(dynamicButton);
}
public void DynamicButton_Click(object sender, EventArgs e)
{
// as you created the control during Page.Load, this event will be fired.
((LinkButton)sender).Visible = true;
}
Im working on a complex ribbon application, so far it is going well but now I have a litle tricky situation where I have to pass value of a DataGridView to a TextBox on another Form after double clicking the the DataGridView.
You have quite a few options actually. And it all depends on the code/architecture of your application, but generally what you are looking for are delegates.
here is an introductory level article for delegates: link. And here is a link to some basic examples which will introduce you to Actions and Lambdas as well.
Or, if those two Forms can see each other (if you have references for both forms in one parent), you can create an event on the source form and subscribe to it on the destination form, and pass the data in that manner.
The Source Form:
• Define the delegate
public delegate void RibbonDataHandler(string);
• Define the event
public event RibbonDataHandler RibbonData;
• Define the method to execute the event
protected virtual void OnRibbonData( string value )
{
if( RibbonData != null )
RibbonData( value );
}
• Invoke the event on the DoubleClick event handler of the DataGridView
string value = // Get Value from the gridView
OnRibbonData( value );
The Destination Form:
• Add a public property to set the TextBox value
public string TextBoxValue
{
get { return txtValue.Text; }
set { txtValue.Text = value; }
}
The Parent Form:
• add those two forms as fields
private Form _sourceForm;
private Form _destinationForm;
• Initialize the forms
// Well, initialize the forms in the way you need it, maybe on the Load event?
_sourceForm = new SourceForm();
_destinationForm = new DestinationForm();
_sourceForm.RibbonData += new SourceForm.RibbonDataHandler(OnRibbonData);
• Define the RibbonData Handler
private void OnRibbonData( string value )
{
_destinationForm.TextBoxValue = value ?? String.Empty;
}
Disclaimer:
I wrote all of this out of my head, did not have VS at this moment, if you have more questions or if something is not working, leave a comment. :)
I am creating a user control where in i have different HTML text boxes and for items like name profession contact etc.
i have a edit and save button for each item. so when i click on the save button i want the value of that text box and update the same in the database . So for this i want to send that value to the ASPX page. but i don't know how to send that value to the ASPX.Also if there is another way to achieve this them please suggest.I am using the three tier architecture.
Thankx
If text box is asp text box or html runat="server" st than you need to expose textbox value as property
public string textData
{
get { return mytextbox.Text; }
set { mytextbox.Text = value; }
}
OR
If you text box is html than make use of Request.QueryString["textboxnameorid"] will provide you data on postback.
if you are using asp.net textbox, you can create public properties in you usercontrol like this
public string Name
{
get { return tbName.Text; }
set { tbName.Text = value; }
}
and this public property can be get set in asp.net page easily..
Regards.