I am creating some controls dynamically in these Dynamic control there is <asp: Image> Control
I want to call webmethod when I click that Image control.I searched a lot but nothing is happening.
the code for Dynamic control is
for (int i = 0; i < SearchResult.Length; i++)
{
System.Web.UI.HtmlControls.HtmlGenericControl panel = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
panel.Attributes["class"] = "panel";
panel.ID = "panel_" + (i + 1).ToString();
System.Web.UI.HtmlControls.HtmlGenericControl inside = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
inside.Attributes["class"] = "inside";
Image img = new Image();
img.ImageUrl = SearchResult[i].ImageUrl;
// img.Attributes.Add("onclick", THE WEB Method I want to call);
inside.Controls.Add(img);
Label label = new Label();
label.Text = SearchResult[i].Title;
label.Font.Size = 10;
label.Font.Bold = true;
panel.Controls.Add(label);
panel.Controls.Add(inside);
test.Controls.Add(panel);
}
and my web method is
[WebMethod]
public static void AddToDownload(String ConnectionString,String Query)
{
SqlConnection con = new SqlConnection(ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand(Query, con);
cmd.ExecuteNonQuery();
con.Close();
}
Get rid of the "onclick" line and wire up a server-side Click event, like this:
protected void Page_Load(object sender, EventArgs e)
{
var img1 = new ImageButton
{
ID = "ImageButton1",
AlternateText = "Button 1"
};
img1.Click += img_Click;
Panel1.Controls.Add(img1);
var img2 = new ImageButton
{
ID = "ImageButton2",
AlternateText = "Button 2"
};
img2.Click += img_Click;
Panel1.Controls.Add(img2);
}
private void img_Click(object sender, ImageClickEventArgs e)
{
var whoClicked = (sender as ImageButton).ID;
}
I have changed your Image server controls to ImageButton server controls to more easily accommodate the Click event.
Each of the two buttons is wired up to a common event handler and then in the event handler it is casting the sender (the control that initiated the event) to an ImageButton and then grabbing its ID to distinguish between the two buttons. You would want to put a null check there in case something besides an ImageButton initiates a click event.
Let me know if you need anything clarified or have further questions.
Related
I need to implement "Edit->Find" function for a WebView2 UI Component using WPF/C#/javascript... Below you will find two examples: One that is made for a TextBox UI Control called MainWindow1, and the other that is implemented for a WebView2 UI Control that is called MainWindows2. I'm giving both examples because I need to work the same way for each one. The TextBox example is working, but the WebView2 example is missing some javascript code to finish it and maybe requires some tweeting of the C# calls to WebView2.
First, I implemented a "Find Forward" button for a TextBox that I can click multiple times to find the next string matching the search pattern in the textbox. And Here's my XML and C# for it:
MainWindow1 GUI:
MainWindow1 XML:
<Window x:Class="WpfApp1.MainWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Loaded="Window_Loaded"
Title="MainWindow1" Height="450" Width="800">
<DockPanel LastChildFill="True">
<StackPanel Orientation="Horizontal"
DockPanel.Dock="Top" Background="Aqua">
<TextBox Name="TboxFind" Width="80" Text="id"/>
<Button Name="FindForward" Content="FindForward"
Click="FindForward_Click"/>
</StackPanel>
<TextBox Name="textbox1" VerticalScrollBarVisibility="Auto"/>
</DockPanel>
</Window>
MainWindow1 C#:
using System.Text.RegularExpressions;
using System.Windows; using System.Windows.Controls;
namespace WpfApp1 {
public partial class MainWindow1 : Window {
public MainWindow1() {InitializeComponent();}
private void Window_Loaded(object sender, RoutedEventArgs e) {
string text1 = "";
for (int i = 0; i < 10000; i++) {
text1 = text1 + "id" + i.ToString() + "\n";}
textbox1.Text = text1;textbox1.Focus();textbox1.CaretIndex = 0;
}
private void TextBoxGotoLine(TextBox textbox1, int linenum) {
var target_cpos
= textbox1.GetCharacterIndexFromLineIndex(linenum);
var target_char_rect
= textbox1.GetRectFromCharacterIndex(target_cpos);
var first_char_rect = textbox1.GetRectFromCharacterIndex(0);
textbox1.ScrollToVerticalOffset(target_char_rect.Top
- first_char_rect.Top);
}
private void FindForward_Click(object sender, RoutedEventArgs e) {
string pattern = #"(?i)(" + Regex.Escape(TboxFind.Text) + #")";
string text1 = textbox1.Text.Substring(
textbox1.CaretIndex + textbox1.SelectionLength);
var match1 = Regex.Match(text1, pattern);
if (match1.Success) {
textbox1.Focus();
textbox1.Select(textbox1.CaretIndex
+ textbox1.SelectionLength
+ match1.Index, match1.Groups[0].Length);
} //if
} //function
}/*class*/ }/*namespace*/
The problem I'm having is that I also need this same feature for a WebView2 UI Control.
So I install the WebView2 UI Control:
WebView2 Install:
PM > Install-Package Microsoft.Web.WebView2
Add to XML: xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
using Microsoft.Web.WebView2.Core;
And here's my corresponding XML and C# demo code that should work the same as the first example I have given:
MainWindow2 GUI:
MainWindows2 XML:
<Window x:Class="WpfApp1.MainWindow2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wv2
="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Loaded="Window_Loaded"
Title="MainWindow2" Height="450" Width="800" >
<DockPanel LastChildFill="True">
<StackPanel Orientation="Horizontal"
DockPanel.Dock="Top" Background="Aqua">
<TextBox Name="SearchStr" Width="80" Text="id"/>
<Button Name="FindForward"
Content="FindForward" Click="FindForward_Click"/>
</StackPanel>
<wv2:WebView2 Name="webview2" CoreWebView2InitializationCompleted
="webview2_CoreWebView2InitializationCompleted" />
</DockPanel>
</Window>
MainWindow2 C#:
using System.Windows; using System.Threading;
using Microsoft.Web.WebView2.Core;
namespace WpfApp1 {
public partial class MainWindow2 : Window {
public MainWindow2() {InitializeComponent(); SearchStr.Focus(); }
private async void Window_Loaded(object sender, RoutedEventArgs e) {
await webview2.EnsureCoreWebView2Async();
}
private void webview2_CoreWebView2InitializationCompleted(
object sender, CoreWebView2InitializationCompletedEventArgs e)
{
string html = "";
for (int i = 0; i < 100; i++) {
string id = "id" + i.ToString();
html = html + "<b>" + id + "</b><br/>";
}
webview2.CoreWebView2.NavigateToString(html);
}
private async Tasks.Task<string> Find(string pattern) {
string js = "";
js = js + "var m1 = document.getElementById(""body"")";
js = js + "/*... ??? what goes here ??? */";
// Find and highlight one at a time, and scroll into view ...
// repeat find from beginning of html body when done ...
// See MainWindow1 example with TextBox for desired behavior here.
return await webview2.ExecuteScriptAsync(js);
}
private void async FindForward_Click(object s, RoutedEventArgs e) {
await Find(SearchStr.Text);
}
}/*class*/ }/*namespace*/
How to use WebBrowser UI Control to do a:
Menu->Edit->Find "SearchStr1"
When I click FindForward Button? I'm thinking it has something to do with executing Javascript on the DOM? each time the button is pressed?
It is possible to call a event click with JavaScript? how?
I'm trying to call this event when a button get clicked.
I'm creating Buttons dynamically so the id's change constantly
Here is how i make the buttons dynamically and assign the event click
protected void Page_Init(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "Pop", "showAndHide();", true);
Button Btn_clic = (Button)sender;
var name = Btn_clic.Text;
List.ListUsers listArea = new List.ListUsers();
List<Data.Area> Area = listArea.AreaList();
List<Data.Area> ListOfEquiposOk = Area.Where(x => x.AREA == name && x.STANDBY == 0).ToList();
List<Button> Botones = new List<Button>();
var TeamFCH = ListOfEquiposOk.Select(x => x.TEAM).Distinct().ToList();
foreach (var team in TeamFCH)
{
Button newButton = new Button();
newButton.CommandName = "Btn" + Convert.ToString(team);
newButton.ID = "Btn_" + Convert.ToString(team);
newButton.Text = team;
newButton.CommandArgument = name;
newButton.Click += new System.EventHandler(newButton_Click);
Botones.Add(newButton);
GoodPanel.Controls.Add(newButton);
newButton.CssClass = "btn-primary outline separate";
}
}
protected void newButton_Click(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "Pop", "ModalGood();", true);
Button Btnclick = (Button)sender;
var team = Btnclick.Text;
string name = Btnclick.CommandArgument;
List.ListUsers listArea = new List.ListUsers();
List<Data.Area> Area = listArea.AreaList();
List<Data.Area> ListOfToolsOk = Area.Where(x => x.AREA == name && x.TEAM == team && x.STANDBY == 0).ToList();
var ToolArea = ListOfToolsOk.Select(x => x.TEAM);
Grv_Eng.DataSource = ListOfToolsOk;
Grv_Eng.DataBind();
}
If you want to assign a OnClick event, do it like this.
Button Btnclick = new Button();
Btnclick.Click += newButton_Click;
Btnclick.Text = "MyButton";
Btnclick.ID = "MyButtonID";
PlaceHolder1.Controls.Add(Btnclick);
And if you want to reference the dynamic ID, use FindControl and ClientID on the aspx page.
document.getElementById("<%= PlaceHolder1.FindControl("MyButtonID").ClientID %>").click
Assign an onClick listener to your button.
document.getElementById("your-id").click = function () {
newButton_Click();
}
Here you go try this for dynamically created buttons
$(document).on('click', '#id', function(){});
You can use a data- attribute to id the buttons from javascript and then you just attach to the javascript event:
So, from the server side you can do this:
newButton.Attributes["data-dynamic-button"] = team;
And you can implement this on the client side:
$("[data-dynamic-button]").click(function (event) {
event.preventDefault()
alert($(event.currentTarget).data("dynamic-button"));
});
EBelow is my code for adding EditText to my layout and it works fine but I want it to create the new EditText boxes below the ones that was created. If you see something in the code I should change or improve, pls comment.Thanks in advance.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_weight_log);
relativeLayout = (RelativeLayout)findViewById(R.id.relativeLayout);
tt= (EditText)findViewById(R.id.tt);
dd = (EditText)findViewById(R.id.dd);
aa = (Button) findViewById(R.id.add);
aa.setOnClickListener(new Button.OnClickListener()
{public void onClick
(View v) { aa();}});
}
public void aa()
{ for(i = 0; i <100; ++i);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relativeLayout);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams (
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.BELOW);
params.setMargins(0,600,0,0);
EditText edtTxt = new EditText(this);
int maxLength = 5;
edtTxt.setHint("editText1");
edtTxt.setLayoutParams(params);
edtTxt.setBackgroundColor(Color.WHITE);
edtTxt.setInputType(InputType.TYPE_CLASS_DATETIME);
edtTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP,18);
InputFilter[] fArray = new InputFilter[1];
fArray[0] = new InputFilter.LengthFilter(maxLength);
edtTxt.setFilters(fArray);
layout.addView(edtTxt);
RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params1.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params1.setMargins(0,600,0,0);
EditText editText = new EditText(this);
int maxLength1 = 4;
editText.setHint("editText2");
editText.setLayoutParams(params1);
editText.setBackgroundColor(Color.WHITE);
editText.setInputType(InputType.TYPE_CLASS_NUMBER);
editText.setTextSize(TypedValue.COMPLEX_UNIT_SP,18);
fArray[0] = new InputFilter.LengthFilter(maxLength1);
editText.setFilters(fArray);
layout.addView(editText);
}
Try changing to linear layout and setting its orientation to vertical. Then if you will add a new view it will be added below your previous view.
I have webpage which gets data by json and then generates html from that data. I want to be able to do element.invokeMember("click"); (webBrowser winForms control) on source generated by JS. How to do that in c#?
I can see the source in firebug only.
What have I already done: ( _ie from here: How to make WebBrowser wait till it loads fully?)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
webBrowser1.ProgressChanged += new WebBrowserProgressChangedEventHandler(_ie);
}
private void _ie(object sender, WebBrowserProgressChangedEventArgs e)
{
int max = (int)Math.Max(e.MaximumProgress, e.CurrentProgress);
int min = (int)Math.Min(e.MaximumProgress, e.CurrentProgress);
if (min.Equals(max))
{
Console.Write("complete");
var menus = webBrowser1.Document.GetElementsByTagName("menu");
Console.Write(menus.Count);
var votes = new List<HtmlElement>();
foreach (HtmlElement menu in menus)
{
Console.Write("found");
var ass = menu.GetElementsByTagName("a");
foreach (HtmlElement a in ass)
{
if (a.GetAttribute("class").Contains("vote-up"))
{
a.InvokeMember("click");
}
}
}
}
}
private void button1_Click(object sender, EventArgs e)
{
webBrowser1.Navigate("xxxxx");
}
}
HTML:
http://pastebin.com/0KGCwtqs
copied from firebug, so some tags are collapsed. I want only <menu>-><footer>-> <a class="vote-up ...">
Console.Write("found") is not executed. So webBrowser can not even find <menu>
solved
Just use tricky JS
var elements=document.getElementsByClassName('vote-up');for (index = 0; index < elements.length; index++) {elements[index].click();}
solved
Just use some js and invoke it from browser
var elements=document.getElementsByClassName('vote-up');
for (index = 0; index < elements.length; index++) {elements[index].click();}
<asp:Button ID="btn" OnClientClick="if(confirm_delete()){
/* post back*/
}else{
return false;
};" OnClick="btnDelete_Click" runat="server" Text="delete"/>
Hi I have this code but I cant do postback for it, im not sure how to?
is it:
<script type="text/javascript">
function CallServer() {
__doPostBack('not sure what goes here','or here');
}
</script>
Then:
<asp:Button ID="btn" OnClientClick="if(confirm_delete()){
/CallServer()/
}else{
return false;
};" OnClick="btnDelete_Click" runat="server" Text="delete"/>
My other script:
<script type="text/javascript">
function confirm_delete()
{
if (confirm("Are you sure you want to delete this comment?")==true)
return true;
else
return false;
}
</script>
EDIT:
On the server side i dynamically add a div to my page with content from my database for each content there is a new div will be added, each div is then refrenced with idWallPosting (so i can call my delete function)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.Odbc;
using System.IO;
public partial class UserProfileWall : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//btn.Visible = false;
string theUserId = Session["UserID"].ToString();
PopulateWallPosts(theUserId);
}
private void PopulateWallPosts(string userId)
{
using (OdbcConnection cn = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver}; Server=localhost; Database=gymwebsite2; User=root; Password=commando;"))
{
cn.Open();
using (OdbcCommand cmd = new OdbcCommand("SELECT idWallPosting, wp.WallPostings, p.PicturePath FROM WallPosting wp LEFT JOIN User u ON u.UserID = wp.UserID LEFT JOIN Pictures p ON p.UserID = u.UserID WHERE wp.UserID=" + userId + " ORDER BY idWallPosting DESC", cn))
{
//("SELECT wp.WallPostings, p.PicturePath FROM WallPosting wp LEFT JOIN [User] u ON u.UserID = wp.UserID LEFT JOIN Pictures p ON p.UserID = u.UserID WHERE UserID=" + userId + " ORDER BY idWallPosting DESC", cn))
using (OdbcDataReader reader = cmd.ExecuteReader())
{
test1.Controls.Clear();
while (reader.Read())
{
System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
div.Attributes["class"] = "test";
div.ID = String.Format("{0}", reader.GetString(0));
// this line is responsible, problem here and my sqlsntax, im trying to set the SELECT idWallPosting for the div ID
Image img = new Image();
img.ImageUrl = String.Format("{0}", reader.GetString(2));
img.AlternateText = "Test image";
div.Controls.Add(img);
div.Controls.Add(ParseControl(String.Format("   " + "{0}", reader.GetString(1))));
div.Attributes.Add("onclick", "return confirm_delete();");
div.Style["clear"] = "both";
test1.Controls.Add(div);
}
}
}
}
}
//protected void btnDelete_Click(object sender, EventArgs e)
//{
// string id = "ctl00_ContentPlaceHolder1_ContentPlaceHolder2_26";
// string[] idFragments = id.Split('_');
// id = idFragments[idFragments.Length - 1];
// //serverside code if confirm was pressed.
// using (OdbcConnection cn = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver}; Server=localhost; Database=gymwebsite2; User=root; Password=commando;"))
// {
// cn.Open();
// using (OdbcCommand cmd = new OdbcCommand("DELETE FROM WallPosting WHERE idWallPosting = " + id + ")", cn))
// {
// cmd.ExecuteNonQuery();
// }
// }
// //PopulateWallPosts();
//}
protected void Button1_Click(object sender, EventArgs e)
{
string theUserId = Session["UserID"].ToString();
using (OdbcConnection cn = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver}; Server=localhost; Database=gymwebsite2; User=root; Password=commando;"))
{
cn.Open();
using (OdbcCommand cmd = new OdbcCommand("INSERT INTO WallPosting (UserID, Wallpostings) VALUES (" + theUserId + ", '" + TextBox1.Text + "')", cn))
{
cmd.ExecuteNonQuery();
}
}
PopulateWallPosts(theUserId);
}
protected void btn_Click(object sender, EventArgs e)
{
string id = "ctl00_ContentPlaceHolder1_ContentPlaceHolder2_26";
string[] idFragments = id.Split('_');
id = idFragments[idFragments.Length - 1];
//serverside code if confirm was pressed.
using (OdbcConnection cn = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver}; Server=localhost; Database=gymwebsite2; User=root; Password=commando;"))
{
cn.Open();
using (OdbcCommand cmd = new OdbcCommand("DELETE FROM WallPosting WHERE idWallPosting = " + id + ")", cn))
{
cmd.ExecuteNonQuery();
}
}
//PopulateWallPosts();
}
}
On my asp.net html side i have:
<script type="text/javascript">
function confirm_delete()
{
if (confirm("Are you sure you want to delete this comment?")==true)
return true;
else
return false;
}
</script>
<p>
<asp:Button ID="btn" OnClientClick="return confirm_delete();" runat="server"
CssClass="Btn" Text="delete" onclick="btn_Click"/>
<asp:TextBox ID="TextBox1" name="TextBox1" runat="server" Rows="3"
Height="47px" Width="638px"></asp:TextBox>
</p>
<p>
<asp:Button ID="Button1" runat="server" Text="Post Message" Width="98px"
onclick="Button1_Click" />
</p>
<p>
</p>
<style type="text/css">
img {border-width:0px; width:100px; height:100px;}
</style>
<div id="test1" runat="server" />
</div>
</asp:Content>
If you notice in my server side code I added this line:
div.Attributes.Add("onclick", "return confirm_delete();")
This works any time I click on my div the confirm_delete is called.
What I was trying to do with my asp.net button was when the div was clicked I could then call the onclick btnDelete_click.
OnClientClick="return confirm_delete();"
That's it...
Edit: __doPostBack works also...
OnClientClick="if(confirm('delete?'))__doPostBack('btn',''); else return false;"
If you really are wanting to manually call __doPostBack(), the first parameter is the .NET generated name for the control. This can be gotten on the server side using Control.ClientID. The second parameter is any extra data that should be passed along in the request. Most of the time I see this field is an empty string.
__doPostBack('ctl100$controlName$id','');
The controlName is the .NET class name of the control I believe, id is the ID you gave the control. To be sure, view the source of the page after it has been rendered in the browser and search for calls to __doPostBack and see how they are formatted.
By a postback in this case do you want to just refresh the page? If so then it would just be:
location.reload();
in your case:
<script type="text/javascript">
function CallServer()
{
location.reload();
}
</script>
Demo (A button click prompts the user to confirm - if they choose Yes, a post back occurs)
See demo here!
One method, not the best for sure:
Add a button into an update panel and set it invisble.
Then call click() method of the button.
Somthing like this:
document.getElementById('button').click();