I'm getting the first element of a table articles where column(statusArticle=false).The problem is that i want to refresh the form after the button click so i can interact with next element, but the form is not refreshed, i tried several codes exept the one of application.restart that is heavy! How can i refresh the form at the boutton click without restarting application?
private void button_Click(object sender, EventArgs e)
{
using (DbEntities db = new DbEntities())
{
Articles firstArticle = db.Articles.FirstOrDefault(u => u.statusArticle == false);
if (firstArticle != null)
{
firstArticle.statusArticle = true;
db.SaveChanges();
MessageBox.Show("Article validated", "OK");
this.Refresh();
}
}
}
Within your class create the following:
private void ShowArticle(Article article)
{
/* The code currently in your constructor for displaying the
first article goes here */
}
For your constructor:
public MyForm()
{
using(DbEntities db = new DbEntities())
{
Articles firstArticle = db.Articles.FirstOrDefault(u => u.statusArticle == false);
if( firstArticle != null ) ShowArticle( firstArticle );
}
}
In your button click handler instead of calling Refresh simple replace it with a call to ShowArticle passing in "firstArticle". The code above could be cleaned up a bit, but it should do.
Related
I have a DataGridView inside a form that displays data from a database every time I load the page like this:
private void LoadList(string Input)
{
fieldsDataGridView.DataSource = null;
List<Field> fields = new List<Field>();
fields = fieldsData.GetAllByTaskId(Input);
List<FieldsDGViewModel> fdgvm = new List<FieldsDGViewModel>();
foreach (var item in fields)
{
var f = new FieldsDGViewModel
{
Id = item.Id,
Name = item.Name,
Order = item.Order,
IsPrint = item.IsPrint
};
fdgvm.Add(f);
}
fdgvm = fdgvm.OrderBy(x => x.Order).ToList();
fieldsDataGridView.DataSource = fdgvm;
fieldsDataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
fieldsDataGridView.Columns["Id"].Visible = false;
fieldsDataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
}
When I double click on an entry in my list, it opens a dialog box containing a form and loads the respective details from that entry. When I save the details, the dialog box closes and in the class where my DataGridView sits, there is this FormClose function that refreshes the DataGridView.
private void FormClosed(object sender, FormClosedEventArgs e)
{
RefreshDataGrid();
RecursiveClearInputs(this.Controls);
fieldIdInput.Text = "";
}
private void RefreshDataGrid()
{
var selected = programInput.SelectedValue;
if (selected != null)
{
var result = programsData.Get(selected.ToString());
if (result != null)
{
programIdInput.Text = result.Id;
LoadList(result.Id);
}
}
if (selected == "-1")
{
RecursiveClearInputs(this.Controls);
programIdInput.Text = "";
fieldIdInput.Text = "";
fieldsDataGridView.DataSource = null;
}
fieldsDataGridView.ClearSelection();
}
However, I am having this issue where the only way that my DataGridView refreshes properly is if I close the main form I am on and reopen it again.
I debugged and managed to capture some results.
Image1: Directly after the Update form is closed. In the fields list, only one entry can have IsPrint = true. However the image shows that both are true.
Image2: After I close and reopen the page containing the DataGridView, it shows this correct result. Only 1 IsPrint = true.
I have tried many methods to solve this issue but I'm not sure why its not refreshing properly.
This is how I open a dialog
EditFields editFields = new EditFields(programIdInput.Text, fieldIdInput.Text, false);
editFields.FormClosed += new FormClosedEventHandler(FormClosed);
editFields.ShowDialog();
EDIT:
I added a dialogresult check but it still doesn't update the datagridview properly. Maybe its a thread issue?
dr = editFields.ShowDialog();
if (dr == DialogResult.OK)
{
RefreshDataGrid();
RecursiveClearInputs(this.Controls);
fieldIdInput.Text = "";
}
I'm just assuming how the OnCklick event looks where you open your Dialog, but I think the problem is that you try to refresh the Datagrid form another Form / Thread. (which will not work)
I suggest you open the dialog form by using ShowDialog and refresh the grid after the Form was closed in the onclick event itself. Try replacing
RefreshDataGrid();
in your FormClosed event with
DialogResult = DialogResult.OK;
Then you are able to handle the grid reloading in your onclick event like this:
EditFields editFields = new EditFields(programIdInput.Text, fieldIdInput.Text, false);
if (editFields.ShowDialog(this) == DialogResult.OK)
{
RefreshDataGrid();
}
else
{
//it was canceled
}
editFields.Dispose();
You need to pass the main form to the detail form.
In the detail form, implement the OnClosing or OnClosed event and call MainForm.LoadList().
I have two forms that need to interact with each other. The parent form has 4 fields and an add button that saves data from each field to an instance of a class object. After its saved to an object the object is stored in a listbox, which the child form contains. I created a custom event to handle that stuff, but I am surely doing something wrong.
What's supposed to happen is that when both windows are open, and there is data in the listbox, whatever item that is selected from the child form listbox fills the parent form fields with the data from that object. When I test out my code, only the first item has the data properly filling the correct fields. If I click any other item after the first selection, the main form fields do not update at all.
Specific to my issue the child form has the following codes:
public EventHandler ListBoxItemClicked;
private void pPotionList_SelectedIndexChanged(object sender, EventArgs e)
{
PotionForm tempMain = new PotionForm(); //this was a test, nothing changed
pPotionList.SelectionMode = SelectionMode.One;
if (ListBoxItemClicked != null)
{
ListBoxItemClicked(this, new EventArgs());
}
tempMain.Refresh(); // this too
}
The parent form has these codes
private void pListDisplay_Click(object sender, EventArgs e)
{
PotionList secForm = new PotionList();
secForm.secFormBox.DataSource = potionBindList;
PotionListChanged += secForm.HandlePotionListChanged;
secForm.ChildPotionListChanged += HandleChildPotionListChanged;
secForm.ListBoxItemClicked += HandleListBoxItemClicked; //this line
secForm.Show();
}
public void HandleListBoxItemClicked(object sender, EventArgs e)
{
pTypeInput.SelectedItem = aPotion._type;
pMagInput.Value = aPotion._magnitude;
pNameInput.Text = aPotion._name;
pBonusInput.Checked = aPotion._bonus;
}
I am currently using Visual Studio Community 2015 if that's relevant.
Ok after seeing all the necessary code I would say that the problem is that you never pass the values from the Child-Form to the Parent. Whenever the event HandleListBoxItemClicked is fired only the initial values of aPotion are written to the controls.
As a solution I would suggest to pass the SelectedItem as the sender when you fire the ListBoxItemClicked event in the childform:
CHILD
public EventHandler ListBoxItemClicked;
private void pPotionList_SelectedIndexChanged(object sender, EventArgs e)
{
Potion p = pPotionList.SelectedItem as Potion;
pPotionList.SelectionMode = SelectionMode.One;
if (p != null)
{
if (ListBoxItemClicked != null)
{
ListBoxItemClicked(p, new EventArgs());
}
}
}
Not you can use this information in the parent form and disperse the information as you please:
PARENT
public void HandleListBoxItemClicked(object sender, EventArgs e)
{
Potion p_parent = sender as Potion;
if(p_parent != null)
{
pTypeInput.SelectedItem = p_parent._type;
pMagInput.Value = p_parent._magnitude;
pNameInput.Text = p_parent._name;
pBonusInput.Checked = p_parent._bonus;
}
}
No refresh or anything else should now be necessary. Hope it helps
Why, after I set SelectedIndex=0, do I subsequently (not in response) get the event handler invoked with SelectedIndex=4? I traced it down to an invocation of a Dispatcher, but I do not understand why.
Here's the plan: I have a page containting a tab control with assorted tabs. When I click on certain kinds of tabs, I want to switch out of this page to another page. The trouble is, when I return to this page, I'm getting looped back out to the other page again, and I can't figure out why.
Specifically, I set SelectedIndex=0, and then [External Code] changes SelectedIndex to 4, causing the page to be switched out again.
// In JobTreePage.xaml
<TabControl x:Name="mainTab"
ItemsSource="{Binding}"
SelectionChanged="mainTab_SelectionChanged">
// in JobTreePage
private void mainTab_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
e.Handled = true;
if (!ready) return;
var ee = this.TryFindResource("Title");
TabItem x = mainTab.SelectedItem as TabItem;
if (x == null) return;
if (IsJobTab(x)) // index 4 is a job tab
{
if (ready ) // assuming the job selected is 1273.
{
ResetTab();
//mainTab.SelectedItem = AddNew;
mw.moldDataButton_Click(sender, e);
}
ready = true;
}
}
public void ResetTab()
{
ready = false;
Application.Current.Dispatcher.BeginInvoke
((Action)delegate { mainTab.SelectedIndex = 0; }, DispatcherPriority.Send, null);
//mainTab.SelectedIndex = 0;
ready = true;
}
And in the MainWindow I have two buttons:
public void moldDataButton_Click(object sender, RoutedEventArgs e)
{
CurrentPage = this.moldDataPage;
moldDataPage.ActivateTab("Project");
// the problem line. problem arises after I click on the Customers button.
Dispatcher.Invoke(new System.Action(() => { }), DispatcherPriority.ContextIdle, null);
Slow_COM_Operation();
}
private void CustomersButton_Click(object sender, RoutedEventArgs e)
{
this.jobTreePage.ResetTab();
CurrentPage = this.jobTreePage;
}
So tracing the program from CustomersButton_Click(), in ResetTab, SelectedIndex == 0, but after that finishes we jump to mainTab_SelectionChanged and see that SelectedIndex == 4. I have no idea what is forcing SelectedIndex to 4.
Aside: Why do I have this dispatcher line? Because I'm attempting to send an asynchronous request via COM interop to get some other stuff happening without the dialog freezing. I don't know how to achieve the goal, but putting in the line at least gives me a page refresh.
I've this program with two web forms. I take the data from one of the web forms through
public GigOpportunity GetData()
{
//Get written data from text boxes from this web form to the other
return new GigOpportunity(txtBoxID.Text, Calendar1.SelectedDate.Date,
TextBoxVenue.Text, TextBoxGenre.Text, Convert.ToDouble(TextBoxCost.Text),
Convert.ToInt32(TextBoxCapacity.Text), CheckHeadLiner.Checked,
TextBoxMainAct.Text, CheckEngineer.Checked);
}
public void ButtonOk_Click(object sender, EventArgs e)
{
// First part: Saves info on first page.
Session.Add("Gig", GetData());
// First part: Saves info on first page.
GigManagerWebForm.add = true;
Server.Transfer("~/GigManagerWebForm.aspx");
}
And I get it to another form through this,
private void Page_Load(object sender, EventArgs e)
{
gigList = new GigList();
AddGig();
}
private void UpdateList()
{
lstGigs.Items.Clear();
for (int i = 0; i < gigList.Count(); i++)
{
lstGigs.Items.Add(Convert.ToString(gigList.getGig(i)));
}
}
public void AddGig()
{
if (add == true)
{
//Reads info into variables on the second page.
GigOpportunity getData = (GigOpportunity)(Session["Gig"]);
gigList.addGig(getData);
add = false;
//Create new session ID
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
}
UpdateList();
}
I simply have no clue why my list only shows me the one item that I lastly add.
In Page_Load you initalize a new GigList to the gigList variable. In AddGig you add a new GigOpportunity to it.
Then in UpdateList, you clear the lstGigs, and add whatever is in gigList to it. There's only one item in gigList, which is the one you just added. That's the reason you're only seeing the last item.
Where and how is lstGigs initialized? It should be populated from some kind of storage before you try to add the new item.
This is because in UpdateList method you clears out the list and you add elements from gigList but on every Page_Load gigList becames new List and addGig adds to it only one item. To resolve the issue you have you probably ought to not clear the ListBox before you add new element. Alternatively you might want to store whole list (not only last added element) in a session. You might as well save that List to ViewState.
I tried the following simplified code on my application and it worked:
public void ButtonOk_Click(object sender, EventArgs e)
{
// First part: Saves info on first page.
if (Session["Gig"] == null)
{
Session.Add("Gig", new List<string>());
}
List<string> list = (List<string>)Session["Gig"];
list.Add("new Data");
Session["Gig"] = list;
Server.Transfer("~/GigManagerWebForm.aspx");
}
// On the GigManagerWebForm.aspx
private void Page_Load(object sender, EventArgs e)
{
AddGig();
}
public void AddGig()
{
if(Session["Gig"] != null)
{
//Reads info into variables on the second page.
List<string> getData = (List<string>)(Session["Gig"]);
ListBox1.Items.AddRange(getData.Select(d => new ListItem(d)).ToArray());
Session["Gig"] = getData;
}
}
Im implementing application which has main window and in this second window which has a lot of tabs in tabcontrol.
On each tab I have a lot of control which values may be edited by user, some of them has to be filled, some need to has values between x and y and so on.
Main windows has got save button. Point is that if in any tab control isnt validated then saving shouldnt be possible and appropriate tab should be opened and validation shown. Could you please tell me any advice of how to create such mechanism ? Maybe any generic methods ?
thanks for help
Try this link
WinForms TabControl validation: Switch to a tab where validation failed
Dictionary<TabPage, HashSet<Control>> _tabControls
= new Dictionary<TabPage, HashSet<Control>>();
public OptionsForm()
{
InitializeComponent();
RegisterToValidationEvents();
}
private void RegisterToValidationEvents()
{
foreach (TabPage tab in this.OptionTabs.TabPages)
{
var tabControlList = new HashSet<Control>();
_tabControls[tab] = tabControlList;
foreach (Control control in tab.Controls)
{
var capturedControl = control; //this is necessary
control.Validating += (sender, e) =>
tabControlList.Add(capturedControl);
control.Validated += (sender, e) =>
tabControlList.Remove(capturedControl);
}
}
}
private void Ok_Button_Click(object sender, EventArgs e)
{
if (this.ValidateChildren())
{
_settings.Save();
this.Close();
}
else
{
var unvalidatedTabs = _tabControls.Where(kvp => kvp.Value.Count != 0)
.Select(kvp => kvp.Key);
TabPage firstUnvalidated = unvalidatedTabs.FirstOrDefault();
if (firstUnvalidated != null &&
!unvalidatedTabs.Contains(OptionTabs.SelectedTab))
OptionTabs.SelectedTab = firstUnvalidated;
}
}