I am trying to style a div which has an asp.net gridview within it.
I am using javascript code.
The div is a popup on asp.net buttonclick event.
I have the code below :
function ViewPopup() {
document.getElementById('PopupDiv').style.visibility = 'visible';
document.getElementById('PopupDiv').style.display = '';
var screenHeight = document.documentElement.clientHeight;
var elementHeight = document.getElementById('PopupDiv').clientHeight;
if (screenHeight > elementHeight) {
document.getElementById('PopupDiv').style.top = ((screenHeight - elementHeight) / 2) + 50 +'px';
}
else {
document.getElementById('PopupDiv').style.top = '10px';
document.getElementById('PopupDiv').style.bottom = '20px';
document.getElementById('PopupDiv').style.overflow = 'scroll';
}
var scrWidth = document.documentElement.clientWidth;
var elWidth = document.getElementById('PopupDiv').clientWidth;
document.getElementById('PopupDiv').style.left = ((scrWidth - elWidth) / 2) - 20 + 'px';
document.getElementById('MaskedDiv').style.display = '';
document.getElementById('MaskedDiv').style.visibility = 'visible';
}
The problem is that .. when the screenheight < elementheight , the control goes to the else statement and a popup
is displayed with scrollbar. Imagine the dimensions of the popup are x and y.
Next time when there is a button click , if screenheight > elementheight, the control goes to the if statement,
but the popup dimensions are again x and y. That is the dimensions are carried from the earlier button click event.
Is there any way I can make sure that the popup fits the gridview perfectly ?
Have you tried putting breakpoints on the var, var and if lines? Then slowly stepping through the code? I'd be curious if "slowing" down the JavaScript allows the correct elementheight and screenheight to be obtained. It's not much of an answer, but I had a similar situation where I had to slow down the code by putting a timer on it so it could get the right dimensions of my element, then continue on to my if statement after the fact. I'd show the code, but that is with a former employer...
I hope in some way this helps.
Related
I'm currently using a WebView2 in my WinUI3 application to display some HTML which is sent from our server.
The HTML itself doesn't contains a body / html tags and is displayed through NavigateToString:
await web.EnsureCoreWebView2Async();
web.NavigationCompleted += async (sender, args) => await sender.ResizeToContent(); // more about this later
web.NavigateToString(someText);
When I display this HTML in my WebView, the WebView's height is always set at 0 by default, and I want my WebView to autosize to its content (I cannot set a fixed sized for its container and stretch the webview to it).
I tried executing scripts found there to evaluate the HTML's size:
How to get height of entire document with JavaScript? :
public static async Task ResizeToContent(this WebView2 webView)
{
var script = "";
var heightString = await webView.ExecuteScriptAsync(script);
int height = 0;
if (int.TryParse(heightString, out height))
{
webView.Height = height;
}
}
Here are 2 differents scripts I tried:
eval(document.documentElement.scrollHeight.toString());
and
;(function() {
var pageHeight = 0;
function findHighestNode(nodesList) {
for (var i = nodesList.length - 1; i >= 0; i--) {
if (nodesList[i].scrollHeight && nodesList[i].clientHeight) {
var elHeight = Math.max(nodesList[i].scrollHeight, nodesList[i].clientHeight);
pageHeight = Math.max(elHeight, pageHeight);
}
if (nodesList[i].childNodes.length) findHighestNode(nodesList[i].childNodes);
}
}
findHighestNode(document.documentElement.childNodes);
return pageHeight;
})();
But in both cases, no mater the HTML provided, it always returns 1040 even with a simple HTML such as <p>test</p>
When I set a fixed height for my WebView, let's say of 60, this p is displayed correctly without scrollbar (while my script would return a height of 1040) BUT when I do some complex HTML intended to be bigger than those 60px, the webview displays a vertical scrollbar.
So all in one, it seems the WebView somehow knows that 1040 is not the real height (otherwise I'd have a scrollbar all the time).
Note that I've also tried to surround my text with <html><body>{myText}</body></html> with the same result.
How can I get the real actual content's height?
Thanks.
After trying other solutions, here is what I came up with which seems to work:
In my ViewModel:
Text = $"<div id='container'>{_source.Text}</div>";
And in my extension method to get the height:
public static async Task ResizeToContent(this WebView2 webView)
{
var script = "eval(document.getElementById('container').getBoundingClientRect().height.toString());";
var heightString = await webView.ExecuteScriptAsync(script);
if (int.TryParse(heightString, out int height))
{
webView.Height = height + 30;
}
}
I had to add the +30 because otherwise the scrollbar was displayed and the webview's content slightly truncated.
Is there any cleaner and less hacky way to do this?
I am working on a very simple table layout application for getting started with learning C#. I am doing everything programmatic ally ( not through design editor)
I am trying to add scrolling onto the application. It seems to work fine, but it does not seem to start at the top of the horizontal range by default. I tried adding things like Max/min size, autoscroll margins etc., but nothing seems to have the desired effect. I am sure there is something simple I am missing.
Here is my current code as it relates to the problem.
layout = new TableLayoutPanel();
layout.Height = 1075;
layout.Width = 704;
layout.Name = "masterLayout";
layout.Dock = DockStyle.Fill;
layout.AutoScroll = true;
int i = 0;
foreach (Race r in ELECTION_DATA.races.OrderBy(o => o.race_id)) {
layout.Controls.Add(new Label { AutoSize = true, Text =r.race_id, Name=r.race_id, Width=300}, i, 0 );
layout.Controls.Add(new TreeView { AutoSize = true, Text = r.race_id, Name = r.race_id, Height = 1000, Width = 300 }, i,1);
i += 1;
}
Controls.Add(layout);
Here is an image, The Label Control Is not visible because the scroll is offset to the beginning of the tree view.
How can I ensure the scroll always starts at the very top?
The ScrollLayoutPanel has a method called ScrollControlIntoView that will move a specific control inside the panel into view. If you just scroll your first control into the view after you are done filling your panels, then that should ensure that the top is visible. In other words:
// do your loop first...
foreach (...)
{
layout.Controls.Add(...);
}
// then if any controls exist, scroll the first control into view
if (layout.Controls.Count > 0)
{
layout.ScrollControlIntoView(layout.Controls[0]);
}
I have a panel control with a label and textbox next to each other. In certain translations the label becomes too long and I'm trying to use GetChildAtPoint to determine when the label has become too long and shorten it appropriately (I know there's other/better ways, but I'm somewhat limited in my approach, hence this option).
I've checked the index and the label is 41, while the textbox is 0.
I use panelControl.GetChildAtPoint(new Point(labelControl.Location.X + labelControl.Width, labelControl.Location.Y)) to try and determine if the label is too long or not, but for some reason, the above code returns the label control instead of the text box.
In debug, labelControl.Location = 566, 305 and textBoxControl.Location = 716, 290. The label control has a width of 202.
I've seen this approach work in other instances and cannot see any differences here, so I'm really unsure as to why it's not working in this scenario.
It seems no problem with your code, please add some testing to see actually size and location change in run time
Eg:
var point = new Point(label1.Location.X + label1.Width,
label1.Location.Y);
var p2 = panel1.Controls[1].Location;
var ctrl = panel1.GetChildAtPoint(point);
if (ctrl is TextBox)
{
textBox1.Text = "Got TextBox";
}
else if (ctrl is Label)
{
textBox1.Text = "Got Label";
}
textBox1.Text += string.Format(" {0}:{1} {2}:{3}", point.X, point.Y, p2.X, p2.Y);
I use this solution(in code below) to add multiply buttons on panel. It works ok but it takes too long, when it tries to add a lot of buttons (for an example 40). I want to ask, if any one knows of a better solution for this situation? I was thinking of creating all possible buttons at program start-up, but in this case will start-up take too long, especially if there will be really lot of buttons (this scenario is possible)?
while (data.Read())
{
btnName = Convert.ToString(data["Name"]);
btnColor = (color == string.Empty) ? Convert.ToString(data["Color"]) : color;
categoryId = Convert.ToInt16(data["CategoryId"]);
//both category and article table's contains this data!
if (categoryId == articleCatId || cl == typeof(Category))
{
Button newbtn = new Button();
newbtn.TextAlign = ContentAlignment.MiddleCenter;
newbtn.Click += (sender, e) => method(sender, e);
newbtn.Text = btnName;
newbtn.Name = "button-" + btnName;
newbtn.Height = size;
newbtn.Width = size;
newbtn.Font = new Font("Microsoft Sans Serif", fontH);
newbtn.Location = new Point(paddingL, paddingT);
newbtn.BackColor = ColorTranslator.FromHtml(btnColor);
location.Controls.Add(newbtn);
num += 1;
if ((num - 1) / inline == 1) { paddingT += size; paddingL = 2; num = 1; }
else { paddingL = paddingL + size; }
}
}
You probably cannot reduce the number of buttons you need to create, so you then have some options to speed it up a little bit:
Add the buttons to an object that is not visible. Only when you're done adding buttons, you make the object visible.
Call SuspendLayout on the parent control to stop it from trying to layout itself. Then call ResumeLayout when you're done adding buttons.
Use a more lightweight control than a button, that is more appropriate for the task. For example a Listbox, Combobox, or several checkboxes or option buttons styled as normal buttons.
Write your own lightweight Button control that does exactly what you want but no more.
I am using ASP.Net and jQuery/jQuery UI and I am trying to use the datepicker control. It works fine on every page, except when I have to use the popup (to add new data into the database and then i refresh the current page to reflect the new data being entered). It seems that document.ready() is failing when I use the popup. I can invoke the datepicker control manually with adding a click event to fire off the showcalendar function, however I want to try and make it work. Does anyone have any ideas of why a popup would fail document.ready() ?
Thanks!
Code in UserInterfaces.js Script File:
$(document).ready(function(){
$(".calendarTrigger").datepicker({showOn:'focus', showAnim: 'fadeIn', changeMonth: true, showOn:'both', buttonImage: '/images/calendar.gif', buttonImageOnly: true, changeYear: true, yearRange: '1950:2010'});
});
Code Calling Popup Functionality:
<a href="#" onclick='javascript:openWindow("/modules/prh/AI.aspx","PH","480","650","","");'
Code For Modal Popup That we use:
function openWindow(url,name,height,width,left,top)
{
if(!width) {width = 625};
if(!height){height = 625};
if(!left) {left = 60};
if(!top){top = 60};
if (!name) {name='mk'};
name = name.replace(" ","");
if ((window.showModalDialog) && (navigator.appName!="Microsoft Internet Explorer"))
{
grayOut(true);
newWindow = window.showModalDialog(url,"name","dialogWidth: " + width + "px;dialogHeight: " + height + "px;resizable: 1;status: 0;scrollbars: 1;dialogLeft: " + left +"px;dialogTop: " + top + "px");
if (newWindow)
newWindow.focus();
grayOut(false);
}
else
{
newWindow = window.open(url,name,'width=' + width + ',height='+ height +
',resizable=1,status=0,scrollbars=1,left=' + left +',top=' + top);
if (newWindow)
newWindow.focus();
else
window.Name.focus();
}
}
function grayOut(vis, options) {
// Pass true to gray out screen, false to ungray
// options are optional. This is a JSON object with the following (optional) properties
// opacity:0-100 // Lower number = less grayout higher = more of a blackout
// zindex: # // HTML elements with a higher zindex appear on top of the gray out
// bgcolor: (#xxxxxx) // Standard RGB Hex color code
// grayOut(true, {'zindex':'50', 'bgcolor':'#0000FF', 'opacity':'70'});
// Because options is JSON opacity/zindex/bgcolor are all optional and can appear
// in any order. Pass only the properties you need to set.
var options = options || {};
var zindex = options.zindex || 50;
var opacity = options.opacity || 70;
var opaque = (opacity / 100);
var bgcolor = options.bgcolor || '#000000';
var dark=document.getElementById('darkenScreenObject');
var tbody = document.getElementsByTagName("body")[0];
if (!dark)
{
// The dark layer doesn't exist, it's never been created. So we'll
// create it here and apply some basic styles.
// If you are getting errors in IE see: http://support.microsoft.com/default.aspx/kb/927917
var tnode = document.createElement('div'); // Create the layer.
tnode.style.position='absolute'; // Position absolutely
tnode.style.top='0px'; // In the top
tnode.style.left='0px'; // Left corner of the page
tnode.style.overflow='hidden'; // Try to avoid making scroll bars
tnode.style.display='none'; // Start out Hidden
tnode.id='darkenScreenObject'; // Name it so we can find it later
tbody.appendChild(tnode); // Add it to the web page
dark=document.getElementById('darkenScreenObject'); // Get the object.
}
if (vis)
{
var pageWidth="100%";
var pageHeight=getPageHeightWithScroll();
if (window.innerHeight>pageHeight)
pageHeight = window.innerHeight;
pageHeight = pageHeight + "px";
//set the shader to cover the entire page and make it visible.
dark.style.opacity=opaque;
dark.style.MozOpacity=opaque;
dark.style.filter='alpha(opacity='+opacity+')';
dark.style.zIndex=zindex;
dark.style.backgroundColor=bgcolor;
dark.style.width= pageWidth;
dark.style.height= pageHeight;
dark.style.display='block';
}
else
{
dark.style.display='none';
}
}
What is the markup for your popup and do you have any other javascript that could possibly cause an error before datepicker fires inside the popup?