Choose a class based on the value in the combobox in C# 2019 - c#-4.0

I have a MainForm window in my C# Window Application. In this form, I have a combo box with 3 values.
Values are Apple, Orange and Banana.
Also I have 3 other classes specifically for these combobox values. Suppose if the user choose Apple in the combobox,
then the class for Apple will be the working module. If the user chooses Banana in the combo, then the working module will be the Banana class.
For example, I run the app. MainForm is loaded. The user chooses Apple from the combobox. Then the class working with MainForm will be the Apple class. ie, In the MainForm, the object of the Apple will be created and access the methods of apple class. If the user chooses Banana, then there should be a way to chose the banana class as the working class with the Mainform. [ie, inside the mainform, the object of the Banana class is created and access the method of the banana
class].
In short, there are some methods in the Apple/Orange/Banana class. And I want to
update the value of these fruits to the labels in the MainForm. So, when I run
the application, the main form will be displayed and the user choose the Apple
value from the combo box. Then the current working module will be Apple class.
When the user click on a button in the Mainform, there is some calculation is going on in the Apple class and the value will be updated the label in the MainClass.[ie, value generated in the Apple class and displayed in the MainForm]
What would be the right way to do this. I am not getting an idea of it.

You could begin by defining a common interface/base class for the fruits. This would serve as the base for creating the collection to be bound to the ListBox. For example,
public interface IFruit
{
string FruitName { get; }
double GetPrice();
}
public class Apple : IFruit
{
public string FruitName => nameof(Apple);
public double GetPrice()
{
return 1.0;
}
}
public class Orange : IFruit
{
public string FruitName => nameof(Orange);
public double GetPrice()
{
return 2.0;
}
}
public class Banana : IFruit
{
public string FruitName => nameof(Banana);
public double GetPrice()
{
return 3.0;
}
}
Now, you could bind the Listbox by creating a List.
var fruitCollection = new List<IFruit>
{
new Apple(),
new Orange(),
new Banana(),
};
fruitListBox.DataSource = fruitCollection;
fruitListBox.DisplayMember = nameof(IFruit.FruitName);
Finally, when you need to execute a method on the selected Item, you could use
var price = (fruitListBox.SelectedItem as IFruit).GetPrice();

Related

Extending PX.Objects.CR.CRMSourcesAttribute

I am trying to add entries to the CRMSourcesAttribute class for more options in the Opportunities Dropdown Box.
I see PXAttributeExtension but apparently this is not meant for developers as I cannot provide a constructor for the base class PXStringListAttribute where the actual values are set.
There must be a simple way to add entries to that dropdown box!
You don't even need to do any customization or programming to change this list. By adding the screen to Automation Steps screen, you can put the Source field in the Fields tab of the automation definition and override the combo box values. Please note that if you're trying that with Acumatica 5.0, you may need to remove the "Opportunities" list as entry point from the generic inquiries, otherwise it will interfere with your selection when you try to select the Opportunities screen from the Automation Steps.
If you want to do it via programming - you'd need to replace the CRMSourcesAttribute on the field with your own version of this attribute. This attribute is fairly simple and is only derived from PXStringList attribute:
public class CRMSourcesAttribute : PXStringListAttribute
{
public const string _WEB = "W";
public const string _PHONE_INQ = "H";
public const string _REFERRAL = "R";
public const string _PURCHASED_LIST = "L";
public const string _OTHER = "O";
public CRMSourcesAttribute() :
base(new[] { _WEB, _PHONE_INQ, _REFERRAL, _PURCHASED_LIST, _OTHER },
new[] { Messages.Web, Messages.PhoneInq, Messages.Referral, Messages.PurchasedList, Messages.Other })
{
}
}

ASP.NET MVC DropDownListFor not selecting the correct value

I'm new in the ASP.NET Framework, I've read the fundamental and have some understanding(theory) on the framework but not much in practice.
I'm struggling with the dropdownlistfor helper method, it comes down to having a weird behavior when i attempt to change the value of the selected item programatically.
In my controller i have the Index action method that receives a parameter of type Tshirt, inside this action method i set the property named Color of the Tshirt object with a value of 2.
In the view (strongly typed) i have a list of colors and pass this list as an argument for the constructor of the ColorViewModel class that will be in charge of returning SelectListItems for my list of colors.
In the view I then set the Selected property of my ColorViewModel object with the value coming from model.Color, now i have set everything so that when i call
#Html.DropDownListFor(x => x.Color, cvm.SelectItems, "Select a color")
I will have my dropdown displayed with the selected item.
When the request(GET) is performed the page is rendered by the browser and the dropdownlist appears with the correct value selected that was established with the value 2 in the Index action method, the dropdown displays "Blue" this is correct.
Then if i select a different item in the dropdownlist (RED, having an id of one) and submit the form, the Save action method is called and i know that the model is reaching the action method with a model.Color=1, which is correct.
Then i decide to redirect to the index action method passing the model object, the index action method changes the Color property back to 2, so when the page is rendered it should display again the value of Blue in the dropdown, but it doesn't, it displays Red.
if you comment out the following line in the Save action method you will get a different behavior.
//tshirt.Color = 3;
i know this logic im following doesnt make much sense from a bussines logic perspective, im just trying to understand what i am doing wrong to not get the expected result.
Given the following model
public class Color
{
public int Id { get; set; }
public string Description { get; set; }
}
I Create the following view model
public class ColorViewModel
{
public int Selected { get; set; }
private List<Color> Colors;
public IEnumerable<SelectListItem> SelectItems { get { return new SelectList(this.Colors, "Id", "Description", this.Selected); } }
private ColorViewModel() { }
public ColorViewModel(List<Color> colors)
{
this.Colors = colors;
}
}
This is my Controller
public class HomeController : Controller
{
[HttpGet()]
public ActionResult Index(Tshirt tshirt)
{
tshirt.Color = 2;
Tshirt t = new Tshirt();
t.Color = tshirt.Color;
return View(t);
}
[HttpPost()]
public ActionResult Save(Tshirt tshirt)
{
//tshirt.Color = 3;
return RedirectToAction("Index", tshirt);
//return View("Index",tshirt);
}
}
And Finally my View
#{
List<Color> colors = new List<Color>(){
new Color(){Id=1, Description="Red"},
new Color(){Id=2, Description="Blue"},
new Color(){Id=3, Description="Green"}
};
ColorViewModel cvm = new ColorViewModel(colors) { Selected = Model.Color };
}
#using(#Html.BeginForm("Save","Home")){
#Html.DropDownListFor(x => x.Color, cvm.SelectItems, "Select a color")
<input type="submit" />
}
I have uploaded the complete code: VS Solution
Because when you redirect, you are passing the updated model
return RedirectToAction("Index", tshirt);

Make attributes mandatory for Groovy Class

I have a Groovy class and want to make sure that certain attributes are always set in the constructor.
Is there any way to way to make attributes mandatory in a Groovy class?
Thanks
You could use #TupleConstructor with specific attribute force :
import groovy.transform.TupleConstructor
#TupleConstructor(force=true)
class Car {
String brand
List options
private boolean sold = false
// constructor
Car(boolean sold) {
this.sold = sold
}
boolean hasBeenSold() { sold }
}
}
car = new Car(true)
assert car.hasBeenSold
More info

Xamarin.ios initialize UIView

I am using Xamarin.iOS. I have created UIView with a few UITextFields. I am looking for best way to initialize text value in these textfields from code.
I can pass text data in the constructor of UIViewContoller, but I don't have access to textFields inside it (they are null). I can change text value of textFields in viewDidLoad method.
I don't want to create additional fields in controller class to store data passed by constructor and use them in viewDidLoad. Do you know better solution ?
I don't want to create additional fields in controller class to store
data passed by constructor and use them in viewDidLoad.
But that's how it's meant to be done.
Alternatively, you can create less fields/properties in your viewcontroller if you use a MVVM pattern:
public class UserViewModel {
public string Name { get; set;}
public string Title { get; set;}
}
public class UserViewController : UIViewController
{
UserViewModel viewModel;
public UserViewController (UserViewModel viewModel) : base (...)
{
this.viewModel = viewModel;
}
public override void ViewDidLoad ()
{
userName.Text = viewModel.Name;
userTitle.Text = viewModel.Title;
}
}
That's the kind of pattern which gives you a lot of code reuse accross platforms (android, WP, ...) and clearly separate concerns. It's a (very) little bit of extra code, but it's worth every byte.

Provide different values for same Import using MEF

This question is pertaining to the usage of MEF.
I want to provide different values for the same import in these two scenarios
[Export("A1", typeof(IA))]
[Export("A2", typeof(IA))]
class A : IA
{
[Import("B")]
public IB B;
}
[PartCreationPolicy(CreationPolicy.NonShared)]
[Export(typeof(IA))]
class A : IA
{
[Import]
public IB B;
}
In both of the two scenarios above, I want to satisfy the import of IB with different values that is when I do this in the first type of export
var a1 = Container.GetExportedValue<IA>("A1");
var a2 = Container.GetExportedValue<IA>("A1");
or this in the second export
var a1 = Container.GetExportedValue<IA>();
var a2 = Container.GetExportedValue<IA>();
I want the two instance of A a1 and a2 to have different values of IB. I don't want to use ImportMany because then I have to decide which one to choose and I want to keep that logic out of class A.
The two scenarios related to these exports are that I want to have a common generic view to work with different types of view models implementing some interface and different instances of a class that provides some service to be configured with different configuration parameters.
Perhaps you are looking for something like this?
public class AExporter
{
[Export("A1", typeof(IA)]
public IA A1
{
get
{
return new A(this.B1);
}
}
[Export("A2", typeof(IA)]
public IA A2
{
get
{
return new A(this.B2);
}
}
[Import("B1", typeof(IB))]
public IB B1 { private get; set; }
[Import("B2", typeof(IB))]
public IB B2 { private get; set; }
}
However, MEF isn't really designed for such fine-grained control over the composition. You could try an alternative like Autofac, which integrates well with MEF.
I don't entirely understand what you are trying to do, but I think you may be able to do it by specifying a creation policy of NonShared on the IB import.
[Import(RequiredCreationPolicy=CreationPolicy.NonShared)]
public IB B;

Resources