Greetings all,
I have a list of "Types" meeting a certain critera that I obtained through reflection. Each of the types is a different feature that the user will potentially choose at runtime. If I add more subclasses later, this dynamic implementation would save my having to remember to update the user control is the idea here.
The list of types is nice, but it'd be nice to display something more meaningful than the Name as it's written in code. For example, instead of "RacingBikeDesigner", I'd like to display "Racing Bike Designer", and maybe even display other properties associated with that type like "Description" so that the user knows what that particular choice does.
So I guess the question is, given a Type, how can I provide a more meaningful representation to the user? Could I maybe add a static field to each subclass and call that from the Type, or could I perhaps use a type converter somehow?
The user control (ListBox, ComboBox, etc) is bound to the return value below, but it's not user-friendly:
List<string> LeftHandedUserChoices = new List<string>();
Type[] AllTypesInThisAssembly = Assembly.GetAssembly(typeof(UserChoices)).GetTypes();
foreach (Type _currentType in AllTypesInThisAssembly)
if (_currentType.IsSubclassOf(typeof(UserChoices)))
LeftHandedUserChoices.Add(_currentType.Name);
return LeftHandedUserChoices;
Cheers,
Q
You have a couple of options for doing this. You could use an attribute on your type for the description, or put it in a static field/property on the Type and retrieve that using reflection.
If localization is an issue, you will probably want to store the resource string name, and display the resource value at runtme.
Add custom C# Attributes to your types.
One method is for you to parse class names based on the naming convention you are using (looks like Pascal in your case). For instance RacingBikeDesigner will become Racing Bike Designer. Here is a parsing example.
Related
I want to have some properties like this
for example I want to have System Permission and it contains properties like SMS,Line, and ...
The UI here is based on the TypeDescriptor view of the object being inspected. Grouping isn't a concept, but it does support sub-objects. The easiest way to do what you want is to simply model the group's as different types, so: have a class that represents System Permission things, with properties for SMS etc. Attributes like [DisplayName(...)] can be used to tweak display with spaces etc. You'd then have an instance of your type as a property on the object being edited.
Everything here can be done without changing the model, but that requires custom type descriptors, which is hard to do and not particularly exciting. Changing the object model is qucker and easier.
I have a (not quite valid) CSV file that contains rows of multiple types. Any record could be one of about 6 different types and each type has a different number of properties. The first part of any row contains the timestamp and the type of record, followed by a standard CSV of the data.
Example
1456057920 PERSON, Ted Danson, 123 Fake Street, 555-123-3214, blah
1476195120 PLACE, Detroit, Michigan, 12345
1440581532 THING, Bucket, Has holes, Not a good bucket
And to make matters more complex, I need to be able to do different things with the records depending on certain criteria. So a PERSON type can be automatically inserted into a DB without user input, but a THING type would be displayed on screen for the user to review and approve before adding to DB and continuing the parse, etc.
Normally, I would use a library like CsvHelper to map the records to a type, but in this case since the types could be different, and the first part uses a space instead of comma, I dont know how to do that with a standard CSV library. So currently how I am doing it each loop is:
String split based off comma.
Split the first array item by the space.
Use a switch statement to determine the type and create the object.
Put that object into a List of type object.
Get confused as to where to go now because i now have a list of various types and will have to use yet another switch or if to determine the next parts.
I don't really know for sure if I will actually need that List but I have a feeling the user will want the ability to manually flip through records in the file.
By this point, this is starting to make for very long, confusing code, and my gut feeling tells me there has to be a cleaner way to do this. I thought maybe using Type.GetType(string) would help simplify the code some, but this seems like it might be terribly inefficient in a loop with 10k+ records and might make things even more confusing. I then thought maybe making some interfaces might help, but I'm not the greatest at using interfaces in this context and I seem to end up in about this same situation.
So what would be a more manageable way to parse this file? Are there any C# parsing libraries out there that would be able to handle something like this?
You can implement an IRecord interface that has a Timestamp property and a Process method (perhaps others as well).
Then, implement concrete types for each type of record.
Use a switch statement to determine the type and create and populate the correct concrete type.
Place each object in a List
After that you can do whatever you need. Some examples:
Loop through each item and call Process() to handle it.
Use linq .OfType<{concrete type}> to segment the list. (Warning with 10k
records, this would be slow since it would traverse the entire list for each concrete type.)
Use an overridden ToString method to give a single text representation of the IRecord
If using WPF, you can define a datatype template for each concrete type, bind an ItemsControl derivative to a collection of IRecords and your "detail" display (e.g. ListItem or separate ContentControl) will automagically display the item using the correct DataTemplate
Continuing in my comment - well that depends. What u described is actually pretty good for starters, u can of course expand it to a series of factories one for each object type - so that you move from explicit switch into searching for first factory that can parse a line. Might prove useful if u are looking to adding more object types in the future - you just add then another factory for new kind of object. Up to you if these objects should share a common interface. Interface is used generally to define a a behavior, so it doesn't seem so. Maybe you should rather just a Dictionary? You need to ask urself if you actually need strongly typed objects here? Maybe what you need is a simple class with ObjectType property and Dictionary of properties with some helper methods for easy typed properties access like GetBool, GetInt or generic Get?
I have couple of questions regarding Sparx EA automation API in C#.
1) How can I get the list of all Types available. For example : Feature, Requirement, Action etc.
2) Is it possible to get the fields applicable to particular type? For example When I wanted to create element of type Action, Priority field is not available for that type. But when I am creating the element of Type Feature, Priority field is there in the screen.
Now, I want to create element of different type using API. So, I need a list of all available fields for particular type. How can I do that?
You can use Repository.GetReferenceList to get a list of available
element types
No that info is not available.
Here is a list of elements used in toolbox.
As far as I know, there is no option.
I'm writing a page with several text fields and a drop down. The fields in the drop down affect the value of the text fields.
For example: the drop down options are "a" and "b". The text fields are "name" and "last name". When choosing "a", "name" is filled with "Joe". When choosing "b", "name" is filled with "Bob".
I've written a class which contains the drop down display name and the values for "name" and "last name".
The question: Design-wise, what's the correct solution - having the class change the text fields, or changing the text fields externally and only accessing the class' data?
Thanks.
P.S - I'm using ASP.Net and Javascript, but this is more of a design issue and not language dependent.
Why do you need to populate an input field with the results of a SELECT change? Can't you get your value directly from the SELECT? What do you do if the user changes the result in the input field? The rule I follow is, if the user is allowed to enter any input, use an input text field. If the user is limited to an array of choices, use a SELECT (or possibly a radio button group).
If it is a long list of choices (longer than your example by a couple orders of magnitude), you can include a filter input where the user can type a few letters and pare the options down to a manageable level, but that is the only case I can think of where you'd want to go the other way with it.
Of course, there may be additional information that's on your mind but haven't imparted here. If so, please elaborate.
Since the class contains all three controls, it is correct that it change the text fields, as it is internal behavior to the class. Now if the fields were all separate classes then it would make more sense to manipulate them externally.
If those select fields and text fields combined work as maybe a widget, then it makes much sense to package them as such in a Class like you have already done. Then as Justin said, operations on these controls should be managed by your class, including keeping all fields synchronized.
If there are enough such widgets to care about, then I'd consider separating the data part of it from the views. Maybe create an additional class that represents the data, and pass an object of that data class to the widget. But pragmatism always comes first.
I'm currently having a problem with a ShoppingCart for my customer.
He wants to be able to add Text between the CartItems so I was wondering if there is some way to still only have one List.
My solution would be to have two lists, one of type IList that gets iterated over when calculating Weight and overall Price of the Cart while having another IList that only exposes the necessary fields for displaying it in the ListView and that is a SuperType of CartItem. (But how do I then access additional fields for the listView, defaulting weight and price to 0 in the Description-Text-Class would break LSP).
But having two lists somehow feels a bit odd (and still gives me problems), so I was wondering if I could do some sort of a TypedList where I specify the Type of each item.
Any suggestions are welcome, I'm not really happy with both options.
Use an interface:
ICartListItem
And make your list be:
List<ICartListItem>
Now, create several types, have all of them implement this interface, and you can store them all safely in your list.
Alternatively, if you want there to be some default logic in a CartItem, use a base class instead of an interface.
You can make a class and, inside of that, define the properties of the required list type and then make a list of same class.
For example, if I wanted to make a list of strings and bools, I would make two properties in one class and then make a list of that class.
The Interface sounds like overkill. I'd just add a property to your current CartItem named something like "TextAfterItem".
Also: make sure your customer understands the cost of this feature in terms of security overhead. It sounds like they think this should be a simple update, but you're allowing users to enter text that will be displayed directly back to the page, and that's a dangerous proposition.