|
I have just written my first C# application that has been released to the wild, so be gentle with me!
The application runs as part of a logon script for all users in a domain to force them to accept network terms and conditions. If they have not previously accepted, a screen is displayed containing a webbrowser control which displays a html file containing the t&c's - the user accepts and a value is stored in the AD and the use is not asked again next time. The t&c's are too large to be displayed in full in the webbrowser without scrolling.
This all works fine, but the customer has asked that the accept/decline buttons are not enabled until the user has scrolled to the end of the HTML document, so the are forced to see (though we can't guarantee that they read) the complete document.
Is there any way of detecting that the user has scrolled to the end of the document? Is any event fired, or is there some other way I can do this?
====================================
Transvestites - Roberts in Disguise!
====================================
|
|
|
|
|
This is relatively painless to do, but requires a little bit of work. What you need to do is place your text inside a div control which will serve as the scroll container - note, make sure that your web browser doesn't have nav bars enabled - this can be a bit confusing. Now, set your div to look like this
<div id="containerDiv" wrap="soft" style="border-style:window-inset; overflow-x:visible; overflow-y:scroll; height="100%"><!-- add your contents here --></div> You need to reference the MsHtml com library and hook that up so that you can get access to the div element. Now, I added a simple UserControl which inherits from the webbrowser, and uses a timer to check the whether or not the scroll height indicates that the end of the page has been reached. Here's the user control:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using mshtml;
namespace LicenseScreen
{
public partial class LicenseControl : WebBrowser
{
private bool _endReached;
private HTMLDivElement _div;
private Timer _timer;
public EventHandler LicenseScrolledToEnd;
public LicenseControl()
{
InitializeComponent();
ScrollBarsEnabled = false;
this.Navigate("about:blank");
}
public void LoadContent(string content, string containerDiv)
{
Document.Write(content);
_div = this.Document.All[containerDiv].DomElement as HTMLDivElement;
EndReached = _div.scrollHeight <= this.Height;
_timer = new Timer();
_timer.Interval = 200;
_timer.Tick += new EventHandler(_timer_Tick);
_timer.Start();
}
void _timer_Tick(object sender, EventArgs e)
{
if (_endReached)
_timer.Stop();
TestLocation();
}
private void TestLocation()
{
EndReached = _div.scrollHeight == (_div.scrollTop + _div.clientHeight) ||
_div.scrollHeight <= this.Height;
}
public bool EndReached
{
set
{
_endReached = value;
if (value)
{
EventHandler handler = LicenseScrolledToEnd;
if (handler != null)
handler(this, EventArgs.Empty);
}
}
}
}
} And here's an example of the code that calls into it:
public partial class LicenseForm : Form
{
public LicenseForm()
{
InitializeComponent();
}
private string BuildPage()
{
StringBuilder sb = new StringBuilder();
sb.Append("<html><head><title>My License</title></head>");
sb.Append("<body>");
sb.Append("<div id='containerDiv' wrap='soft' ");
sb.Append(" style=\"border-style:window-inset; overflow-x:visible; overflow-y:scroll; height='100%'\">");
for (int i = 0; i < 300; i++)
{
sb.AppendFormat("<p>This line represents line {0} in my license</p>", i);
}
sb.Append("</div></body></html>");
return sb.ToString();
}
private void LicenseForm_Load(object sender, EventArgs e)
{
licenseControl.LicenseScrolledToEnd += new EventHandler(licenseControl_PropertyChanged);
licenseControl.LoadContent(BuildPage(), "containerDiv");
}
void licenseControl_PropertyChanged(object sender, EventArgs e)
{
btnAccept.Enabled = btnCancel.Enabled = true;
}
}
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
I have finally got it working in a demo project (not your fault - I'm just slow!)
Many thanks
Chris
====================================
Transvestites - Roberts in Disguise!
====================================
|
|
|
|
|
I had one problem with it - when I tried to use my html file, everytime it checked its scroll position, it was detecting that it was at the end of the file and activated the button, but the scrollbar was disabled. I finally tracked it down to a DOCTYPE directive in the first line of the file. When I removed this, it worked perfectly.
The line causing the problem was:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
====================================
Transvestites - Roberts in Disguise!
====================================
|
|
|
|
|
Further research shows that the problem occurs whenever there is a on the fly as well, as the html is provided and maintained by the client, so I can't be sure that someone is not going to screw up the file and remove the DIV
====================================
Transvestites - Roberts in Disguise!
====================================
|
|
|
|
|
I wanna saving picture in sql2005 with varbinary data type and retrieve it in C# but every code I find is in sql 2000 with image data type. please help me.
|
|
|
|
|
You would save it with something like this:
private void SaveImageToDb(string fileName, SqlConnection sqlConnection)
{
using (MemoryStream ms = new MemoryStream())
{
Image.FromFile( fileName ).Save( ms, System.Drawing.Imaging.ImageFormat.Bmp );
using (SqlCommand sqlCmd = new SqlCommand(
"INSERT INTO MyTable(MyImage) VALUES (@Image)", sqlConnection ))
{
sqlCmd.Parameters.Add( "@Image", SqlDbType.Image );
sqlCmd.Parameters [ "@Image" ].Value = ms.GetBuffer( );
sqlCmd.ExecuteNonQuery( );
}
}
} I've just knocked this up in the web editor, so I apologise if the syntax isn't 100% perfect.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Hi Pete,
I think that would work just fine, however you got me puzzled here, for two reasons.
1.
Not sure why, but the OP actually asked for a VarBinary field, not an Image field.
2.
The way you suggest the data moves from file to Image to MemoryStream to byte array (BTW the Image isn't disposed of). IMO you could have used File.ReadAllBytes() avoiding all conversions and copy operations, the one drawback is it would not detect a bad image.
I guess I'm missing something.
TIA.
|
|
|
|
|
Luc Pattyn wrote: Not sure why, but the OP actually asked for a VarBinary field, not an Image field.
Oops. With all the use of Image in the OP, I got confused and used code for the Image type.
Luc Pattyn wrote: The way you suggest the data moves from file to Image to MemoryStream to byte array (BTW the Image isn't disposed of).
Yup - but I was just coding this up quickly in the editor. In reality, I would have used a copy of our full image management suite, which I touched very briefly on here[^].
Luc Pattyn wrote: I guess I'm missing something.
The only thing you are missing is that I hacked this together in the CP text editor.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Your padawan says thanks.
|
|
|
|
|
Based on what Pete already offered, I would try this:
private void SaveImageToDb(string fileName, SqlConnection sqlConnection)
{
using (SqlCommand sqlCmd = new SqlCommand(
"INSERT INTO MyTable(MyImage) VALUES (@Image)", sqlConnection ))
{
sqlCmd.Parameters.Add( "@Image", SqlDbType.VarBinary);
sqlCmd.Parameters [ "@Image" ].Value = File.ReadAllBytes(fileName);
sqlCmd.ExecuteNonQuery( );
}
}
}
Warning: MSDN on SqlDbType.VarBinary holds a comment on size; something happens around 8000 bytes!
|
|
|
|
|
And that would do it nicely.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
using (SqlConnection sqlConnection = new SqlConnection(strConn))
{
sqlConnection.Open();
foreach (string file in fileList)
{
FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
byte[] byteImage = new byte[fileStream.Length];
fileStream.Read(byteImage, 0, (int)fileStream.Length);
string commandText = "Insert into ImageTable(ImagePath, Image)Values(@ImagePath, @Image)";
SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection);
sqlCommand.Parameters.Add("@ImagePath", SqlDbType.Text);
sqlCommand.Parameters.Add("@Image", SqlDbType.Binary);
sqlCommand.Parameters["@ImagePath"].Value = file;
sqlCommand.Parameters["@Image"].Value = byteImage;
sqlCommand.ExecuteNonQuery();
System.Windows.Forms.Application.DoEvents();
}
}
|
|
|
|
|
Hi,
How to make a part of the text as superscript in button text. Thanks in advance.
|
|
|
|
|
In order to do this, you have to take responsibility for drawing the button yourself. You should search for owner drawn buttons in Google or Bing.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Hi,
I have loaded the image after resized to 800x600 (from original image size). but the image aligned at center (picture box size mode is in zoom). how can i align the image at left corner.
code for resize the image
private void resizeimage(Image my, Size sz1)
{
double ratio = 0d;
double myThumbWidth = 0d;
double myThumbHeight = 0d;
int x = 0;
int y = 0;
Bitmap bp;
if (f == false)
{
if ((my.Width / Convert.ToDouble(sz1.Width)) > (my.Height /
Convert.ToDouble(sz1.Height)))
ratio = Convert.ToDouble(my.Width) / Convert.ToDouble(sz1.Width);
else
ratio = Convert.ToDouble(my.Height) / Convert.ToDouble(sz1.Height);
}
else if (f == true)
{
if ((Convert.ToDouble(sz1.Width) / my.Width) > (Convert.ToDouble(sz1.Height)) / my.Height)
ratio = Convert.ToDouble(my.Width) / Convert.ToDouble(sz1.Width);
else
ratio = Convert.ToDouble(my.Height) / Convert.ToDouble(sz1.Height);
}
myThumbHeight = Math.Ceiling(my.Height / ratio);
myThumbWidth = Math.Ceiling(my.Width / ratio);
Size thumbSize = new Size((int)myThumbWidth, (int)myThumbHeight);
bp = new Bitmap(sz1.Width, sz1.Height);
x = (sz1.Width - thumbSize.Width) / 2;
y = (sz1.Height - thumbSize.Height);
System.Drawing.Graphics g = Graphics.FromImage(bp);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
rect = new Rectangle(x, y, thumbSize.Width, thumbSize.Height);
g.DrawImage(my, rect, 0, 0, my.Width, my.Height, GraphicsUnit.Pixel);
pictureBox1.Image = bp;
|
|
|
|
|
I got it. I put Zero '0' instead of x and y coordinates. now there is lot of space on right hand side how i remove this.
|
|
|
|
|
How to bring an excel in to windows form. The excel sheet should displayed with in the windows form. Please help
|
|
|
|
|
Hi
Is there any tool to show the ASP.Net application latency when we increase the load ?
Thanks
|
|
|
|
|
I think (haven't checked), but think there is a bunch of performance counters available in the Performance Monitor application with the OS.
There are tools available on the net, some free, just search google for "ASP.Net stress test" etc.
|
|
|
|
|
Hi everyone
How to insert the records in the dataset into the database. i tried the adapter.update(ds). but it does not work...
thank you for reading
zheng
|
|
|
|
|
DataAdapters, and Update in particular, are very limited in what they can do -- I avoid them.
I've forgotten the details, but generally (for SQL Server):
0) Set a Command : INSERT INTO table (field0 ... ) VALUES (@Param0 ... )
1) Create the parameters : cmd.Parameters.Add ( new SqlParameter ( "@Param0" , typeof(whatever) ) )
2) Iterate the rows of a DataTable : foreach ( DataRow dr in ds.Table [ i ].Rows )
2.1) Set the parameter values : cmd.Parameters [ 0 ].Value = dr [ 0 ] ...
2.2) Execute the cmd : cmd.ExecuteNonQuery()
3) Repeat as necessary
I prefer to encapsulate this into a method so I don't need to remember it.
|
|
|
|
|
hi
thank you for reply!
below is my code:
string SelectSchema = "SELECT * FROM [Package Data Range]";
DataSet ds = new DataSet();
OleDbDataAdapter adapterPkInfo = new OleDbDataAdapter(SelectSchema, ImportCon);
OleDbCommandBuilder cmdBldr = new OleDbCommandBuilder(adapterPkInfo);
adapterPkInfo.FillSchema(ds, SchemaType.Source, "PackageDataRangeSchema");
DataSet ds2 = new DataSet();
string selectPkInfo = "SELECT * FROM [Package Data Range]";
OleDbDataAdapter adapter = new OleDbDataAdapter(selectPkInfo, connection);
adapter.Fill(ds2, "Package Data Range");
ds.Tables[0].Merge(ds2.Tables[0],true,MissingSchemaAction.Ignore);
my dataet has around 200 columns. it is not efficient to repeat that....
thank you
zheng
|
|
|
|
|
shoubi wrote: it is not efficient to repeat that
Indeed, but as long as you want to insert all of them, you can loop through the columns and cobble up the Insert statement and parameters.
|
|
|
|
|
yup. thank you very much! however just want to check with you the "adapter.update()" how does it work? does it require any commands? or it is smart enough to act accordingly?
thank you!
|
|
|
|