Close C# form but not close calling application? - c#

What I have is a project that is called from our ERP. The ERP calls functions that are exposed in the C# project and info is passed back and forth. This works great, but I am having an issue with the "Cancel" button. When the cancel button is clicked I want it to jsut close the C# form and not return anything.... Pretty much just terminate any action in C# and sever the connection to the ERP. I have tried many forms of the environment and application commands but they also close the ERP as well as the C# form. Are there any recommendations of the best approach for this? I can send the dialog from the button back to the ERP and just have the ERP not do anything with a true value but I am wondering if there isn't a more efficient way to accomplish this. Thank in advance.
Edit: Here is the current code on the form that contains the buttons. The cancel button is and has been set with DialogResult = Cancel as well...
The problem is that certain functions will be called from the ERP when this form is instantiated. Using this.close() does close the form but it also returns values back to the ERP, which I do not want it to do.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace NavAutomation
{
public partial class NAVForm : Form
{
public NAVForm(string frmName, int maxLen)
{
InitializeComponent();
}
private void NAVForm_Load(object sender, EventArgs e)
{
}
public string RetVal1 { get; set; }
public string txtB1 { get; set; }
public int txtB1Len { get; set; }
private void button2_Click(object sender, EventArgs e)
{
this.RetVal1 = textBox1.Text;
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
Application.Exit();
}
}
}

What I ended up doing, which works great is default a bool to true, and pass back false on the cancel button/close button and then simply exited the calling code in our ERP and it works like a dream. Thanks for the comments.

Related

C# API in Winforms

I have this code to generate random jokes from an API and I want it to output a joke to a listbox after pressing a button. But I cant put it working... Im kinda new so any hints to help me pls? Thank you! :)
My code:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Windows;
using System.Windows.Forms;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JokeGEN
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
static readonly HttpClient client = new HttpClient();
public class Value
{
public int id { get; set; }
public string joke { get; set; }
public List<string> categories { get; set; }
}
public class Root
{
public string type { get; set; }
public Value value { get; set; }
}
private void button2_Click(object sender, EventArgs e)
{
Task<string> responseBody = client.GetStringAsync("http://api.icndb.com/jokes/random");
listBox1.Items.Add(responseBody.Result);
Root jokes = JsonConvert.DeserializeObject<Root>(responseBody.Result);
string joke = jokes.value.joke;
}
}
}
First of all: separate your model from how you display your model (your view). Apart from that your code will be better to reuse, it will also be easier to unit test and thus to debug. If later you decide that you want to view your jokes differently, you won't have to change the model.
private async Task<string> FetchJokeAsync()
{
using (var client = new HttpClient())
{
const string requestUri = "http://api.icndb.com/jokes/random";
string responseBody = await client.GetStringAsync(uri);
return responseBody;
}
}
About async-await: Every method that uses async-await, has to be declared async. Return Task instead of void, and Task<TResult> instead of TResults. There is only one exception: event handlers return void instead of Task.
await inside the async method. The return value of await is the TResult. It is convention to append the identifier of the method with async.
By the way, HttpClient implements IDisposable. This means that the designer of the class thought that it holds scarce resources. It is convention not to keep IDisposable object longer alive then needed. You have to weigh the costs of construction against the cost of holding a scarce resource, but since you are doing this as a result to a button click, I guess you won't do this ten times per second. So reconstructing the Client is no problem.
Apparently you want to display the fetched jokes in a ListBox. You need a method for this:
private void DisplayJoke(string joke)
{
this.listBoxJokes.Items.Add(joke);
}
Now to fetch the Joke and Display the fetched joke whenever the button is clicked:
private async void OnButtonCreateJoke_ClickedAsync(object sender, ...)
{
string joke = await this.FetchJokeAsync();
this.DisplayJoke(joke);
}
Remember: OnButtonCreateJoke is an async event handler, the return value should be void, not Task.
If this does not work, it will be easy to debug it. First replace the JokeFetcher:
private async Task<string> FetchJokeAsync()
{
await Task.Delay(TimeSpan.FromSeconds(1)); // simulate some wait time
return "This is a Joke";
}
What happens? Is the joke displayed correctly, then apparently the problem is in this method. If not displayed correctly: Try to debug DisplayJoke: what happens if you display it in a Text Box?
private void DisplayJoke(string joke)
{
this.textBox1.Text = joke;
}
By now you should know whether the problem is in your joke fetching or joke displaying.
Conclusion
By separating the model (= how to get a joke) from the view (=how to display the joke) it is way easier to understand what happens, to test your code, and thus to debug your code, it is way easier to change the requirements: if you need to display the joke in a TextBox, changes are minimal.

C# I'm trying to create a web user control with custom classes, and I am getting a Object not set to an instance of an Object Error

I hope you can help me with this. I am creating an internal webforms asp.net site to display a list of internally used documents in different categories.
I decided to create a custom document class to put in a list to hold the documents, and then a custom web user control to display the documents wherever they want them on the site.
The documents class is in a general class file in my App_Code folder.
cabinet.cs
public class Document
{
private string _Url;
private string _Title;
public Document(string URL, string Title)
{
_Url = URL;
_Title = Title;
}
public string URL
{
get { return _Url; }
set { _Url = value; }
}
public string Title
{
get { return _Title; }
set { _Title = value; }
}
}
This code works just fine. Then in my user control I create a list of type document and initiate it in Page_Load(). Then I created a public method to add new documents to the list.
DocDisplay.ascx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class DocDisplay : System.Web.UI.UserControl
{
private List<Document> _DocList;
protected void Page_Load(object sender, EventArgs e)
{
_DocList = new List<Document>();
}
public void Add(string URL, string Title)
{
_DocList.Add(new Document(URL, Title));
}
public void WriteDocuments()
{
foreach (Document doc in _DocList)
{
Response.Write($"<span class='document'><a href='{doc.URL}'>{doc.Title}</a></span>");
}
}
}
I am getting the error in the add method. It says that my object is not to an instance of an object. But I do that in Page_Load.
index.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
pageDocs.Add("index.aspx", "Hello World!");
pageDocs.Add("index.aspx", "Red Rum");
pageDocs.Add("index.aspx", "Lorum Ipsum");
}
I have registered my user control in my index page.
<%# Register Src="~/DocDisplay.ascx" TagPrefix="uc" TagName="DocDisplay" %>
<uc:DocDisplay ID="pageDocs" runat="server" />
So I am not exactly sure why I am getting that error. As far as I can tell, there is nothing wrong with my code. If you could help I would greatly appreciate it.
Events get fired starting from the root of control hierarchy and end at the leaf nodes. Index.Page_Load is being called before DocDisplay.Page_Load has an opportunity to instantiate the list.
The _DocList field needs a value before it can be used by anything, so initialization needs to happen as early as possible. This is accomplished very easily with a field initializer. Declare and assign it all at once:
private List<Document> _DocList = new List<Document>();
When the Index class instantiates its child controls early in the page life cycle, _DocList will immediately have an object reference.
It's tempting to say, "Page_Init will be called sooner; I'll do it there." This may work at first, but if you do any dynamic control loading, you'll soon find out that it's a balancing act. A dynamically loaded control has to play event catch-up, so its Init event can be fired after statically loaded controls have started firing Load events. It's important to use each event for its purpose, and not for its timing, and use constructors (and field initializers) to initialize non-control class state.

Relationship between ComboBox & ListBox

I have a DataSet setup like the following:
As can be seen, there's a relationship between both tables.
In my form page I have the following layout:
The combobox simply select the 'platform' and what I want to get is that the ListBox only shows records that belongs to the relationship, filtered by plataforma_id.
In the TableAdaptor of the Table 'SetupUrlConditions' I have set it up like the following:
When I run the app, the ListBox always shows all records instead of being filtered by the relationship. Changing the ComboBox selected item, the result is always the same.
So, Is there something missing in my code to accomplish this?
Thanks.
EDIT:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Backoffice
{
public partial class SetupRules : Form
{
public SetupRules()
{
InitializeComponent();
}
private void plataformasBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.plataformasBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.plataformasDataSet);
}
private void SetupRules_Load(object sender, EventArgs e)
{
this.plataformasTableAdapter.Fill(this.plataformasDataSet.plataformas);
this.setupUrlConditionsTableAdapter.Fill(this.plataformasDataSet.SetupUrlConditions);
}
}
}
private void PlatformasCBO_SelectedValueChanged(object sender, EventArgs e)
{
if (PlatformasCBO.SelectedValue != null)
{
SiteUrlLstBox.DataSource = this.platformasDataSet.SetupUrlConditions.Where( p => p.platforma_id == (int)PlatformasCBO.SelectedValue).ToList();
}
}
Ok you made me dig for that one since I haven't done it in such a long time...
Combobox = Platformas. Properties to be set are DisplayMember = Plaformas, ValueMember = Id
ListBox just displaymember = condicion?... up to you from there.
Keep in mind that something is always selected with this setup it would need to be modified to have nothing selected initially but out of scope for the question

error : 'classA' doesnot exist in current context

I started new project of Windows Forms. First page is UserLogin. in form load event I am taking the logintable from database into memory.
I am using a class in which all read and write operations methods are stored.
when I am calling the class in formload event, the error comes "doesnot exist in current context"
I may be missing some references or headerfilename..
Please Help
Thanks in Advance
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Web;
namespace InvestmentAndReturns
{
public partial class UserLogin : Form
{
public UserLogin()
{
InitializeComponent();
CenterToScreen();
}
public string UserID = null;
private string userPass = null;
public string UserGroup = null;
DataTable UserLoginTable;
int logintry = 1;
public bool LoginStatus = false;
private void Form1_Load(object sender, EventArgs e)
{
txtUserID.Select();
string cmd = "Select * from UserLogin";
UserLoginTable = DbRdRw.SqlDbRead(cmd, "UserLogin");
}
DbRdRw: this is the Class
SqlDbRead: this is read method
i have included that class by directly pasting it in the project folder and then opened solution and then included in the project
It looks like you have copy pasted source file containing definition of DbRdRw from some other project - which mostly means the namespace declaration in the file will be from older project.
Things will work if you change the namespace to your current project InvestmentAndReturns.
However, why are you copy pasting this around? You could make a library dll for your DbRdRw and reference the dll. That way you will keep your source code at one place.

Refreshing EF data binding in WPF

I use Entity Framework ObjectResult coming from Execute method to bind data to a WPF control, like here:
using System;
using System.Data;
using System.Data.Objects;
using System.Windows;
using System.Linq;
namespace Microsoft.Samples.Edm
{
/// <summary>
/// Interaction logic for SalesOrders.xaml
/// </summary>
public partial class SalesOrders : Window
{
private AdventureWorksEntities context;
private int customerId = 277;
private void SalesOrdersForm_Loaded(object sender, RoutedEventArgs e)
{
// Instantiate the ObjectContext.
context = new AdventureWorksEntities();
// Define a query that returns orders for a customer.
// Because lazy loading is on by default, SalesOrderDetails
// related to a SalesOrderHeader will be loaded when the query
// is executed.
var query = from o in context.SalesOrderHeaders
where o.CustomerID == customerId
select o;
// Execute the query and bind the result to the OrderItems control.
this.orderItemsGrid.DataContext = ((ObjectQuery)query).Execute(MergeOption.AppendOnly);
}
private void buttonClose_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
public SalesOrders()
{
InitializeComponent();
}
}
}
The example comes from MSDN
It work fine, but how do I refresh the binding? Either programmatically or when database changes?
The SalesOrdersForm_Loaded code should be seperated from this event.
Place this code in a function. and call it in form load. Now you can call this function on your requirement basis.
I hope it makes sense.
Edit
You can call this function on button click / Timer or any event based on your requirement to update the bindings

Categories

Resources