I am writing a database management GUI for a company. There are several forms and they are binding to a database created from Access. Forms are like Employer, Vacancies and so on.
I am writing a function to generate and print all Vacancies information. One Vacancy each page. I am using some Currency manager to control where to find the vacancyID from Vacancy table.
// get the Vacancy record matching the Vacancy ID from the Vacancy record
int aVanID = Convert.ToInt32(drVanReport["VacancyID"].ToString());
cmVacancy.Position = DM.VacancyView.Find(aVanID);
//As soom as the app run at this line, ERROR HAPPENED.
DataRow drVan = DM.dtVacancy.Rows[cmVacancy.Position];
Then I use Graphics g = e.Graphics; g.drawing to generate my document for print preview.
private void btnVacancies_Click(object sender, EventArgs e)
{
if (vacancies == null)
{
vacancies = new Vacancies(DM, this);
}
vacancies.ShowDialog();
//ERROR POINTED TO HERE! SAYING Object reference not set to an instance of an object.
}
This error should not happen?? My codes is not actually about opening this form, although my button is on this form. This form is surely existing and opened successfully just now. Why is it null now?? I used try..catch..throw it too. But my document still cannot generate any data for print preview.
Can someone tell me how should I adjust my code to avoid this error and generate printing preview successfully? Thanks.
Maybe only some one who has ever done similar application could understand the context.
Related
In our website, we are using the ReportViewer control to display SSRS reports. When the user clicks the link for a report, the code stuffs some initial variables to present the proper report, i.e.:
reportViewerNew.ServerReport.ReportServerUrl = new Uri(ReportURL);
reportViewerNew.ServerReport.ReportPath = ReportPath + ReportName;
Every Report has been created with at least one Parameter called "userName". On the report this is a hidden Report Parameter, and the value gets passed down into the Stored Procedure that populates the report so we can track who is requesting the information.
So, in the code we have a Switch block to load up an Array (the length depends on which Report is being called upon) that has at the very least this "userName":
default:
RptParameters = new ReportParameter[1];
RptParameters[0] = new ReportParameter("userName", UserID);
break;
With the array established, we then pass the pre-loaded values into the Report Parameters through the SetParameters method:
reportViewerNew.ServerReport.SetParameters(ReportParameters());
This all works great, and when the report runs I can check our database and see that the "userName" value has been passed down to our tracking.
However... this stops working if the report requires some interaction by the user to run the report -- for example choosing an option in one dropdown loads up a dependent dropdown, choosing a date that loads a dropdown with related choices, etc. It seems that this "internal postback" of the report is causing the Hidden Report Parameter "userName" to loose its value, and what then gets passed down is the account we use for the database connection.
I have placed a break-point in the code on the if (!Page.IsPostBack) line to catch the Report's "postback" but this is not being triggered... it seems to be internal to the ReportViewer control. I have tried looking up some kind of EventHandler for this postback in the documentation (https://learn.microsoft.com/en-us/dotnet/api/microsoft.reporting.webforms) but not seeing it.
Does anyone know why the Report Parameter would be losing its value, how to prevent it, or if I need to be handling this in a different way?
We are doing the exact same thing but using an Mvc.ViewUserControl wrapper to use the control in an MVC Project. Adding to the MVC project requires us to turn off Async rendering, but these steps may still work in your case, if not with a little tweaking.
We still set the parameters in the Page_Load method, so that the intial report call has the "userName" parameter set, but we also inject the parameter on every postback call like this:
Create a delegate method for the "SubmittingParameterValues" Report Viewer event:
private void ReportViewerNew_SubmittingParameterValues(object sender, ReportParametersEventArgs e)
{
ReportParameter userNameParam = e.Parameters.Where(rp => rp.Name.ToLower().Equals("username")).FirstOrDefault();
if (userNameParam != null)
{
userNameParam.Values.Clear();
userNameParam.Values.Add(UserID); // Assign your value here
}
}
Assign the delegate function to the report viewer in the Page_Init function. This will intercept the parameters every time before the report is sent to the server:
protected void Page_Init(object sender, EventArgs e)
{
reportViewerNew.SubmittingParameterValues += ReportViewerNew_SubmittingParameterValues;
}
That's it!
We have a report that displays at the PageFooter which payment way the customer used to pay an order, in that area we have three other TableObjects that are working correctly, but there's one that executes a script to build manually the TableObject, the problem we located is when it executes that script it fails showing the message StackOverflowException in System.Drawing.dll
The message on top means the report generation is executing.
The script that I located it fails is this one, if this script is not executing the report displays correctly but without the information we want to display in that TableObject
private void TableModalidadPago_ManualBuild(object sender, EventArgs e)
{
// get the data source by its name
DataSourceBase rowData = Report.GetDataSource("DOCUMENTO_MODALIDAD_PAGO");
// init the data source
rowData.Init();
if (rowData.RowCount == 0)
{
TableModalidadPago.Visible = false;
return;
}
// print the first table row - it is a header
TableModalidadPago.PrintRow(0);
TableModalidadPago.PrintColumns();
TableModalidadPago.PrintRow(1);
TableModalidadPago.PrintColumns();
// now enumerate the data source and print the table body
while (rowData.HasMoreRows)
{
// print the table body
TableModalidadPago.PrintRow(2);
TableModalidadPago.PrintColumns();
// go next data source row
rowData.Next();
}
TableModalidadPago.CanBreak = false;
TableModalidadPago.CanGrow = true;
}
It fails at line
TableModalidadPago.PrintRow(0);
And if I put the TableObject in other section that is not the PageFooter it works perfectly.
Anyone knows if there's any restriction to execute code at PageFooter or if there's any error at the provided script?
I already posted this information in FastReports forum but still no answer(Link)
Edit: I also created a ticket in FastReports Support centre and still no answer...
Edit2: 24/06/2016 today I saw they published a new version of the FastReports.Net (2016.3 previous was 2016.2) and I downloaded and install it, after cleaning up my project and tried again, the error still ocurring, with this new version the program just unexplectly closes and doesn't display any error message, I updated my ticket with support center
Thanks.
The stack overflow error suggests that the while loop may be infinite. Could it actually be failing at the line
TableModalidadPago.PrintRow(2);
Perhaps you need to remove rows from rowData object once you've printed them?
(Please see the edit on the bottom of the question, if you do not want to read the whole story.)
Hi,
I am new to stackoverflow. Don’t get me wrong, I use it quite often. But up until now I never actually posted something. This is because I did not have something new/useful to say and my English is not that good. The first thing (might have) changed, the latter did not.
I ran into a problem at a customer's Windows 7 system quite recently. I was shipping a C# .Net 4.0 Windows Forms application via ClickOnce. Basically, it is an application that creates a bitmap file and shows it to the user. If the bitmap exists prior to the creation, the existing file gets deleted first. After that the new file is created and loaded by a PictureBox.
The following thing occurred at the customer’s system: After starting the application the first creation succeeds – the second and all following ones do not. The file cannot be deleted, because some process is blocking it. This process is the application itself.
System.IO.IOException: The process cannot access the file “filename” because it is being used by another process.
Well, of course that is nothing unusual. The thing is I tested the application on several systems. None showed this exception. And until now I am unable to see an code error.
So I looked a little bit closer on the customer’s system: The only difference I could find is, that they changed the users folder so that they are not located on the windows partition, but on a different one (C:\Users --> D:\Users). I searched for an instruction on the internet and did the same thing on one of my test systems. To my surprise I got the same exception when I ran my application on it.
With that I could change my code so that the exception does not occur anymore. But I do not understand why that is. So maybe there is something wrong with my code and the error just reveals itself under that special circumstances. Or maybe the code is okay and the reason lies somewhere else. I just hoped that you might be able to help me.
So here is some code I put together, that shows the same behavior. I used 3 buttons, an OpenFileDialog and a PictureBox on a Form. First thing to do is to choose an image file. By pressing one of the two remaining buttons it gets copied into the main folder of the application. After being copied it is shown by the PictureBox. By the way, it does not seem to matter if it is a ClickOnce-application or a “normal” one.
String m_FileName;
private void btnChooseFile_Click(object sender, EventArgs e) {
if(openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) { // If file was chosen, set file name for later use and activate buttons.
m_FileName = "Test" + Path.GetExtension(openFileDialog1.FileName);
}
}
private void button1_Click(object sender, EventArgs e) {
// This is not working.
if(this.pictureBox1.Image != null) {
//Image img = this.pictureBox1.Image; // I was not sure, if maybe the pictureBox somehow prevents the disposing of the image, as long as it's assigned to it.
//this.pictureBox1.ImageLocation = null; // So I set them null, both the image and the image location.
//this.pictureBox1.Image = null;
//img.Dispose(); // Then I disposed the image.
this.pictureBox1.Image.Dispose(); // The short version. It is not working either way.
this.pictureBox1.Image = null;
}
(new FileInfo(openFileDialog1.FileName)).CopyTo(m_FileName, true); // But still this is where the Exception occurs.
this.pictureBox1.Load(m_FileName);
}
private void button2_Click(object sender, EventArgs e) {
//This is working.
if(this.pictureBox1.Image != null) {
//Image img = this.pictureBox1.Image;
//this.pictureBox1.Image = null;
//img.Dispose();
this.pictureBox1.Image.Dispose();
this.pictureBox1.Image = null;
}
(new FileInfo(openFileDialog1.FileName)).CopyTo(m_FileName, true);
pictureBox1.Image = Image.FromFile(m_FileName);
}
What happens now is the following: If I start the application and click button1 twice, I will get the exception (on the second click). If I start it and click button2 twice, I will not. If I start the application and click buttons1 first and after that button2, I will get the exception. So, the Picture.Load-Function somehow blocks the file, even if I dispose it.
When I searched on the internet, I found an article from microsoft: http://support.microsoft.com/kb/309482/en-us. But it does not hit the bull's eye.
Take into account, that both versions are working on all my test machines. I just get the exception when I change the users folder to a non-windows-partition.
Why is that? And where is the difference in the presented versions?
Edit
Okay, because of the first and only reaction so far, it seems to me, that it is still not clear, what really happens: If I take the above code, put it in a Windows Forms application, compile it and run it on different computers (at work, at home, does not matter) it works - both button1 and button2 (with the Click-functions linked to them) can be used as often as I like - no exception thrown. If I run the application on a computer, where I changed the users folder, and click button1 the second time - bam - IOException, file locked by process. Button2 works as long as I do not press button1.
The first answer implies, that I should get the locking on every system. But I DO NOT (as long as I do not change the users folder)! I tested it on every single computer I could get my hands on - no IOException. I set up a new system, just to rule out some special changes to the systems in my company - both buttonx_Click functions worked - no exception either. I even compiled the program on another computer - same behavior. The only three systems to throw that exception were the ones with the changed users folder.
So far I have no clue, why this difference in behavior occurs. Can somebody help me?
Anybody?
Yes, this is normal. Happens on any operating system, doesn't have anything to do with the Users folder location. The PictureBox.Load() method was intented to be used to load images from locations other than the file system. Like a web site. Which is slow, it avoids freezing the UI while the download is taking place.
It internally uses a FileStream when it discovers that the url you pass is actually a file and not a website name. This FileStream does not get disposed until the PictureBox itself is disposed or you call the Load() method again. A requirement because Image.FromStream() requires the stream to remain readable until the image is no longer used. It is this FileStream that keeps a lock on the file. Disposing the PictureBox.Image is not enough to also dispose the FileStream, the Image object doesn't know that it is being displayed inside a picture box.
There are several ways to solve this problem:
Use the Image property instead of Load(), assign it from Image.FromFile(). Disposing the Image now also releases the lock on the file. As you found out
Keep a dummy image around, one that perhaps displays a "Loading..." bitmap. Load() it first to release the lock on the file
Dispose the PictureBox and recreate it.
This works and unlocks the file
Image img= Image.FromFile(mypath);
Graphics g = pictureBox1.CreateGraphics();
g.DrawImage(img,0,0);
img.Dispose();
I follow the steps in this page http://blogs.msdn.com/b/visualstudio/archive/2009/12/09/building-and-publishing-an-extension-for-visual-studio-2010.aspx
I create a TextAdornment project and a search box. I wan to do some different in this page. I want to query a link , get a list in the WPF user control and then write the info into the editor back. so the question is I do not know how to write the text back into the editor in seachbox(WPF user control)?
I searched a lot, and get a way to use the code look like this:
IVsTextManager txtMgr = (IVsTextManager)GetService(typeof(SVsTextManager));
IVsTextView vTextView = null;
int mustHaveFocus = 1;
txtMgr.GetActiveView(mustHaveFocus, null, out vTextView);
IVsUserData userData = vTextView as IVsUserData;
if (userData == null)
{
return null;
}
else
{
IWpfTextViewHost viewHost;
object holder;
Guid guidViewHost = DefGuidList.guidIWpfTextViewHost;
userData.GetData(ref guidViewHost, out holder);
viewHost = (IWpfTextViewHost)holder;
return viewHost;
}
However, the method "GetService" also said not found. I think the reason is this method is for VSPackage. and it is not suitable for Adornment project.
Please help to point how the write the text back into the editor from WPF user control. Thanks!
======================================================================================
Solution:
when creating the SearchBox(WPF User Control), pass through the IWpfTextView to WPF control.and then,it is possible to use this in SearchBox.xaml.cs. Also need to be aware to use the Dispatcher function to keep the UI thread is the active one.
Dispatcher.Invoke(new Action(() =>
{
ITextEdit edit = _view.TextBuffer.CreateEdit();
ITextSnapshot snapshot = edit.Snapshot;
int position = snapshot.GetText().IndexOf("gist:");
edit.Delete(position, 5);
edit.Insert(position, "billmo");
edit.Apply();
}));
The code you have there is if you're in a package and you are trying to figure out what view is currently active...it's overkill for what you're trying to do.
Assuming you started from the TextAdornment template, the adornment object is given an IWpfTextView in the constructor. (If not, you probably have an implementation of IWpfTextCreationListener.TextViewCreated which got it and you need to thread it through.) The IWpfTextView derives ITextView which has a property ITextBuffer. From here, you can call CreateEdit() and edit text from there.
My company has gone from 2 people to 4 people recently and I have had to add user tracking and the like. With that said I am now trying to tackle a way for people to see when others are in a record. I have a datagridview that is a case selector and when someone double clicks it opens the main form for that case. I need to be able to across users be able to show or at the very list stop them from going into that record. I have absolutely not idea how to do this in winforms and am hoping someone could help me modify what I already have to do this.
The code being used to open the form is below:
private void caseSelectorDataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
System.Data.DataRowView SelectedRowView;
//newCityCollectionDataSet.PropertyInformationRow SelectedRow;
newCityCollectionDataSet.CaseSelectorRow SelectedRow;
SelectedRowView = (System.Data.DataRowView)caseSelectorBindingSource.Current;
SelectedRow = (newCityCollectionDataSet.CaseSelectorRow)SelectedRowView.Row;
frmSummary SummaryForm = new frmSummary(this);
SummaryForm.LoadCaseNumberKey(SelectedRow.CaseNumberKey, true, null);
SummaryForm.LoadBRTNumberKey(SelectedRow.BRTNumber, null);
SummaryForm.LoadWaterByAdd(SelectedRow.Num, SelectedRow.Direction, SelectedRow.Name, null);
SummaryForm.Show();
}
You could create an activity table with the userID and casenumber they're currently modifying, and then check it to see if any other user is modifying the same case.