Windows forms adding the same binding second time causes argument exception - c#

I bind "Enabled" property of button to datasource member. I use Infragistics.Win.Misc.UltraButton control and its method DataBindings.Add( System.Windows.Forms.Binding ). The button is on dialog form. When I open dialog for the first time binding is added ok. After I close dialog and open it second time I get exception in System.Windows.Forms.ControlBindingsCollection.Add(Binding binding), message says that "Enabled" property of button is read-only. How to solve this?
Dialog opening code is like this:
using (PickItemDialog dialog = new PickItemDialog())
{
dialog.ViewModel = new PickItemViewModel();
dialog.ViewModel.Items = new BindingList<T>(records.ToList());
dialog.ViewModel.Title = title;
dialog.ViewModel.Notification = notification;
if (dialog.ShowDialog() == DialogResult.OK)
return (DataItem)dialog.ViewModel.SelectedItem;
}

Related

C# Can't change labels and button properties from a dialogbox

I have my main form and a dialogbox which is called from main. In my main form I have a label and a button that which properties I can't change. I'm using Visual Studio 2015, not sure if there is a bug regarding this. I also made sure my label and button are set to public to modify.
Code: (this is from the dialog box, this has a list box the function is triggered at selectindexchange)
else if ((short)lbDiscountTypes.SelectedValue == 2) //Senior
{
frm_Main main = new frm_Main();
main.VAT = false;
main.labelStatus.Text = "NON-VAT (SENIOR)";
main.labelStatus.BackColor = System.Drawing.Color.IndianRed;
main.labelStatus.ForeColor = System.Drawing.Color.WhiteSmoke;
main.btnNonVat.Enabled = false;
main.btnNonVat.BackColor = System.Drawing.Color.SlateGray;
main.btnNonVat.ForeColor = System.Drawing.Color.Navy;
main.labelVatAmount.Text = 0.00m.ToString();
main.Dispose();
//INQUIRE DISCOUNT TYPES
var Discount = GC.CSHR_DiscountTypes.Where(Filter => Filter.DiscountCode == (short)lbDiscountTypes.SelectedValue);
decimal DP = 0.00m;
foreach (var item in Discount)
{
DP = item.DiscountPercentage;
}
foreach (var item in GC.CSHR_SORepo
.Where(Filter => Filter.Machine == MACHINE
&& Filter.SalesOrderNum == SALESORDERNUM
&& Filter.First_SRP == Filter.IMFSRP))
{
item.DiscountAmount = (item.SoldSRP * DP) / 100;
item.TotalAmount = (item.Quantity * item.SoldSRP) - item.DiscountAmount;
item.VATableSalesOnTotalAmount = (item.Quantity * item.SoldSRP) - item.DiscountAmount;
item.VATRate = 0.00m;
GC.SaveChanges();
}
Close();
}
The code below //INQUIRE DISCOUNT TYPES works well but not the one on top.
I've used debug mode to check if the lines are not being skipped over and they aren't.
You should pay attention to:
You are creating a new instance of your main form that you don't need (while it is open behind the dialog), so you need to get it not create a new instance
You are disposing the main form you created. main.Dispose();
In fact you are creating a new instance of main form and assigning values to those controls and then dispose it. While and instance of yor main form that you expect to see changes on it, is open and untouched behind your dialog.
To set value of those controls you can do one of these ways:
Option 1
Make your labelStatus and btnNonVat public. Open your main form in designer and select labelStatus and btnNonVat and in property grid, set Modifier to public. Then write this code:
//var main = Application.OpenForms.OfType<frm_Main>().FirstOrDefault();
var main = (frm_Main)Application.OpenForms["frm_Main"];
main.labelStatus.Text = "NON-VAT (SENIOR)";
main.labelStatus.BackColor = System.Drawing.Color.IndianRed;
main.labelStatus.ForeColor = System.Drawing.Color.WhiteSmoke;
main.btnNonVat.Enabled = false;
main.btnNonVat.BackColor = System.Drawing.Color.SlateGray;
main.btnNonVat.ForeColor = System.Drawing.Color.Navy;
main.labelVatAmount.Text = 0.00m.ToString();
Option 2
Pass an instance of your frm_Main to your dialog and work with it.
Option 3
After closing the dialog, use values from dialog and set values of your main form
Looks like you are trying to create new form using frm_Main main = new frm_Main(); syntax. All you need to do is get the instance of your current form.
var _currentMainForm= Application.OpenForms[0];
or if you have given name to your form
var _currentMainForm = Application.OpenForms["MainFormName"];
Once you get the reference you can perform all your label updates.
The code on top creates a new form, changes the labels and then disposes the form.
I think you should change the labels of the existing form.
Like in the other answer said you are setting properties of controls into a new Form object and not in the form where you come from.
You should pass the form object into the parameters of the dialog, something like:
void myDialog(frm_Main callingForm)
{
callingForm.Textbox1.Text = "abc";
}
And call it from you main form like this
...
myDialog(this);

Open form with Form Name in winform appliaction

I want to ask what should i do to open form with the help or class name in winform c#?
I have three different forms
UserManagement
GroupsManagement
LocationManagement
I get permission from database for these three forms
in menu click i fill tag Property with the name of form like this
tsmMain.Tag = item.PermissionName
tsmMain.Click += new EventHandler(tsmMain_Click);
what i want to do is to open form dynamically in button click and to remove these if condition?
Can i do this with reflection or else??
ToolStripMenuItem aa = sender as ToolStripMenuItem;
var tag = aa.Tag;
if (tag == "User Management")
{
UserManagement oUserForm = new UserManagement();
oUserForm.Show();
}
if (tag == "Groups Management")
{
GroupManagement oGroupForm = new GroupManagement();
oGroupForm.Show();
}
You may be able to do something like this, using the name of your form, as a string argument:
var form = (Form)Activator.CreateInstance(Type.GetType("YourNameSpace.UserManagement"));
form.Show();
One straightforward, but not necessarily very clean solution would be to store the forms right there in the Tag property of your menu items, rather than the strings.
Somewhere at the beginning of your application, you'd have to assign these instances:
myUserManagementItem.Tag = new UserManagement();
myGroupsManagementItem.Tag = new GroupManagement();
Then, in the click event, you could shorten your code to:
ToolStripMenuItem aa = sender as ToolStripMenuItem;
Form form = aa.Tag as Form;
form.Show();
Cleaner solutions would include the following:
Provide separate event handlers for different menu items.
Derive your own menu item types that store the form to show in a strongly-typed property.

Adding a CheckBox to WPF MessageBox

The Message Boxes of WPF could be customized as i understand.
I was wondering is it possible to add a CheckBox to the WPF MessageBox with say - Don't show this message again etc.?
Possible, you can change the WPF control styles and templates as per your requirement, see these links for further references:
Custom Message Box
http://blogsprajeesh.blogspot.com/2009/12/wpf-messagebox-custom-control.html
http://www.codeproject.com/Articles/201894/A-Customizable-WPF-MessageBox
http://www.codeproject.com/Articles/22511/WPF-Common-TaskDialog-for-Vista-and-XP
Could just use a Window
Passed checked in the ctor so you can get the value back
bool checked = false;
Window1 win1 = new Window1(ref input);
Nullable<bool> dialogResult = win1.ShowDialog();
System.Diagnostics.Debug.WriteLine(dialogResult.ToString());
System.Diagnostics.Debug.WriteLine(checked.ToString());
I realize this is a very old thread, but I was searching this matter today and was surprised to see no replies mentioning Ookii: https://github.com/ookii-dialogs/ookii-dialogs-wpf
I was already using it for Folder Browsing. Now I wanted to add a "Don't Show Again" checkbox whenever the main window is closed, and it's really simple to use it.
Here's my code:
using Ookii.Dialogs.Wpf;
//create instance of ookii dialog
TaskDialog dialog = new();
//create instance of buttons
TaskDialogButton butYes = new TaskDialogButton("Yes");
TaskDialogButton butNo = new TaskDialogButton("No");
TaskDialogButton butCancel = new TaskDialogButton("Cancel");
//checkbox
dialog.VerificationText = "Dont Show Again"; //<--- this is what you want.
//customize the window
dialog.WindowTitle = "Confirm Action";
dialog.Content = "You sure you want to close?";
dialog.MainIcon = TaskDialogIcon.Warning;
//add buttons to the window
dialog.Buttons.Add(butYes);
dialog.Buttons.Add(butNo);
dialog.Buttons.Add(butCancel);
//show window
TaskDialogButton result = dialog.ShowDialog(this);
//get checkbox result
if (dialog.IsVerificationChecked)
{
//do stuff
}
//get window result
if (result != butYes)
{
//if user didn't click "Yes", then cancel the closing.
e.Cancel = true;
return;
}

PopUp Window WPF Form Custom Control Content

I have a form done in WPF which has a custom control already on it called RateView. This custom control has 4 textboxes (which are all working as they should be). It also contains a button.
I have a second custom control called Extended Margin Info, which also has a XAML Form which will just show output data only.
How can I by clicking the button on the custom control called Rateview bring up the XAML canvas onto my Main window of the extendedmargin info XAML, in the same position everytime? Rateview control exists 5 times on the main window therfore there will be 5 buttons that when clicked, will need to output the popup of ExtendedMargin Info to the main screen in the same position each time with the content of extendedmargin info.
Your button, when clicked, should call a Command which updates a Property of some ViewModel that exposes the ViewModel of the current ExtendedMarginInfo you want to display. Then you can bind this property to the Content Property of a ContentControl in the target view. You can select the View you want the Control to display by using the ContentControl.ContentTemplateSelector property.
I guess you want show one popup and change it's content placing in it different controls.
At 1st create your custom control:
balloon = new LogEntryInfoBalloon();
balloon.SetMainWindow(this);
balloon.DataContext = vm.NotificationViewModel;
Then create Popup control (System.Windows.Controls.Primitives):
localPop = new Popup();
localPop.AllowsTransparency = true;
localPop.Placement = PlacementMode.AbsolutePoint;
localPop.StaysOpen = true;
localPop.PlacementTarget = this;
localPop.Child = balloon;
Placement target points to MainWindow.
Define timer that will close(hide) balloon:
localPopTimer = new Timer(new TimerCallback(CloseLocalPopup));
Close func:
private void CloseLocalPopup(object args)
{
var act = new Action(() =>
{
localPop.IsOpen = false;
});
Dispatcher.BeginInvoke(act, null);
}
Show balloon code looks like this:
private void ShowNotifyBaloon(NotifyBaloonViewModel vm)
{
var act = new Action(() =>
{
localPop.IsOpen = true;
localPopTimer.Change(4000, Timeout.Infinite);
});
Dispatcher.BeginInvoke(act, null);
}

InvalidOperationException when enumerating through a list of results to provide multiple textbox's with text

I have a data entry form with many textbox's and some dropdowns for the user to input data. When the user selects a "Location" from the dropdownlist, they can click a button on top of the form to view a popup with more details according to that location. The data successfully automates when the popup loads but when the user tries to close the popup and continue with the main form, an unhandled exception occurs for the system.InvalidOperationException. The error specifically occurs because "The collection I'm Enumerating through has been changed". Although I'm not changing anything I guess something behind the scenes is happening, here is my code to retreive the data:
string postalCode;
string phone1;
string phone2;
string supervisor;
var ObjectContext = new ObjectContext();
var qry = (from i in ObjectContext.TableLocation
where i.LocationName == LocationValue
select i).ToList();
foreach (var data in qry)
{
postalCode = data.postalCode;
phone1 = data.phoneNumber1;
phone2 = data.phoneNumber2;
supervisor = data.supervisor
}
txtPostalCode.Text = postalCode;
txtPhone1.Text = Phone1;
txtPhone2.Text = Phone2;
txtSupervisor.Text = supervisor;
The LocationValue is linked to a Public variable that the parent form fills with whatever is selected in the location dropdownlist:
public string CountyValue
{
get { return txtCountyName.Text; }
set { txtCountyName.Text = value; }
}
Is there a better way to enumerate through this list of values and supply them to textbox.text? I have tried everything to fix this error.
EDIT
Also all my database columns are Varchars so there was no need to convert data types.
And I only get this error when I deploy my app via ClickOnce to clients PC.
From what I see, that Location is a single value, and there is no need to create a List. So that means you can avoid iterating over a list, and do this instead:
var ObjectContext = new ObjectContext();
var details = ObjectContext.TableLocation
.First(x => x.LocationName == LocationValue)
.Select(x =>
new {
PostalCode = x.postalCode,
Phone1 = x.phoneNumber1,
Phone2 = x.phoneNumber2,
Supervisor = x.supervisor
});
txtPostalCode.Text = details.PostalCode;
txtPhone1.Text = details.Phone1;
txtPhone2.Text = details.Phone2;
txtSupervisor.Text = details.Supervisor;
ADDED:
Also check this MSDN Reference, according to it, there are several scenarios where ShowDialog() could throw an InvalidOperationException, that are unrelated to LINQ-to-SQL or EF.
ADDED: From that MSDN article it says this:
When a form is displayed as a modal dialog box, clicking the Close
button (the button with an X at the upper-right corner of the form)
causes the form to be hidden and the DialogResult property to be set
to DialogResult.Cancel. Unlike non-modal forms, the Close method is
not called by the .NET Framework when the user clicks the close form
button of a dialog box or sets the value of the DialogResult property.
Instead the form is hidden and can be shown again without creating a
new instance of the dialog box. Because a form displayed as a dialog
box is hidden instead of closed, you must call the Dispose method of
the form when the form is no longer needed by your application.
memoize items(.ToArray()) before collection iterations
var qry = (from i in ObjectContext.TableLocation.ToArray()
where i.LocationName == LocationValue
select i).ToList();

Categories

Resources