I have a WPF application that has two combo boxes, one with what I'm calling a FileType and one with Actions (add, edit, delete, etc.). Every FileType has a corresponding class. What I'm trying to do is for example if FileTypeA is selected and the action is Add then I want to do something along these lines:
void myMethod(string FileType, string Action)
{
//using reflection find class from the FileType string, and call method Action
var x = new FileTypeA();
x.Add();
}
if the user selects FileTypeB and Delete then the object created and the method called will change accordingly. I think this might be possible using reflection, but I'm trying to find out if there is even a better way using perhaps a generic class? since all these FileType classes are very similar.
try to create an interface IFileType with basic methods Add,Delete,Save
Implement this interface on all fileTypes classes e.g DocFile,PdfFile etc.
Bind the List to ComboBox and use its selected Item object as cast it as IFileType and call its method via interface(Delete/Save) without doing any reflection.
I would recommend using MVVM pattern so that you can easily create separation of layer and have benefits of OOP.
If you aim to call a certain action for item according to the selected option from ComboBox, get familiar with delegates. Then use the approach of binding a collection of options (with the delegate included) to ComboBox
Related
I am pretty new to programming in c#. I have a listview (ListViewProjects) box in ProjectListForm but I want to be able to access the items in the listview box in AddProjectForm. How can I access them? I was going to try to do something like this
ProjectListForm.ListViewProjects.Items.Clear
but when I type in ProjectListForm., ListViewProjects isn't an option.
You can either set the list view's design time options to generate a public member (in control's properties, under Design set Modifiers to Public), or possibly better you could add a public property to ProjectListForm to expose either the list view or just the Items collection, eg:
public class ProjectListForm : Form
{
...
public ListView.ListViewItemCollection ProjectsListViewItems
{
get { return ListViewProjects.Items; }
}
}
The best way IMO is to write public methods in ProjectListForm that do what you're trying to achieve in AddProjectForm, such as ProjectListForm.ClearProjects(). That way you're not forcing AddProjectForm to depend on the implementation of ProjectListForm, say if you later want to change to a TreeView.
You cannot achieve this way in C#. you need to create the instance of the object.
To do this you have to create the method in ProjectListForm and in that methos you have to call this.ListViewProjects.Items.Clear.
Now from the AddProjectForm you have to call this method of the running instance of ProjectListForm.
If you want to know more about how to make the call, then please give the flow about how do you show the AddProjectForm from the ProjectListForm.
I've created a sample app, just to test and try out some of wpf's capabilities. I was basically trying out the databinding in wpf, and did the rest of stuff more or less quickly. THen, i faced an arquitectural problem (yes, should have thought in advance before starting coding :) ) and i wanted to know what's the best refactoring solution for it.
I have a simple interface that returns a list of objects, based on a defined process.
public interface IDoStuff<out T>
{
IEnumerable<T> Do(string someParam);
}
i've created a couple of implementations for this interface. Then i have a view in wpf, which has a dropdown with hardcoded values, and depending on what you select, instatiates the implementation of the interface and populates some list
foreach (var item in new IDoSTuffImplementation1()<MyObj>.Do("imp 1"))
{
MyObjs.Add(item);
}
ater on MyObjs is the DataContext for a listview, and displays things and so on and so forth, but it's out of the main question.
this is all hardcoded and not very nice. If i was ever to implement a new interface, i'd need to add it to the dropdown, and create a new foreach for that specific implementation (more duplicated code)
Ok, here's my impression on making this better/refactoring for extensibility.
I was thinking a good approach would be to use some kind of MVVM pattern, making the wpf view into a view + viewmodel. the viewmodel would use some kind of IoC like spring, which would (by xml) instantiate one specific implementation of the interface, and inject it to the viewmodel, which would then call its "Do" method and everyone happy. So this way, the only thing that would be needed to do when we implement a new component, is to add it to the xml config file.
Suggestions, Comments? what's the best approach, if any?
thanks!!
Actually I don't see any architecture changes if you provide another implementation of the interface. You already have a good architecture when using MVVM, so the task you are trying to accomplish will not change the architecture, but will extend your application using the architecture.
I suggest you change you Method to a Property instead. And assign that property to ComboBox's ItemsSource property to ease up your coding using data binding.
I need your opinion on this because I have read a lot of different things on the subject. If you have a List<T> or any kind of list within a class declaration do you make it private and then add or remove items using specific methods or do you make it public?
Your views would be much appreciated with any disadvantages/advantages of each option.
To give an example let's say we have a class Employer with private fields name and List<Employees>. My question is if we should make the employees list private or public and what the advantages/disadvantages be on either case.
for List explicitly yes it should be private depending on what the functionality you're exposing is supposed to do, interfaces such as IEnuemerable, ICollection or IList would be a better choice or if you're exposing a collection See SLaks reply.
Generally exposing internal structure and state is a bad idea and since your object of type List is both, you would want to keep it internal.
It might make sense to give the user the ability to iterate over it, to add or remove items to it but you should still keep the List internal and either expose Add/Remove methods or as a minimum expose an interface making it possible to change the type of the internal representation with out affecting the public interface.
Further more if you are exposing using an interface you should go for the narrowst possible interface.
So if the client code only needs to enumerate it. use IEnumerable if client code needs to index use ICollection and so forth.
further if you expose as an IEnumerable you should make sure that what ever you return is in fact read only by either using a read only collection class or by use of an iterator block
EDIT after update
In regards to your example. Ask yourself does it make sense that any one except the Employer can change who his employees are? to me that's in the words you've chosen already. The Employer employs the Employee and should have full control over who his/hers employees are. So in this particular case I'd keep it private and expose Hire(IEmployee employee) and Fire(IEmployee employee) that way the code plainly states the intent
If you need to expose a collection to your class' users, you should make a readonly property with a System.Collections.ObjectModel.Collection<T>.
You can then inherit this class and override InsertItem, RemoveItem, and SetItem to run custom logic when the user manipulates the collection.
If you don't want the user to be able to change the collection, you should expose a ReadOnlyCollection<T>.
In your specific example, you should probably expose a ReadOnlyCollection<Employee> with separate mutator methods in Employer.
And if all you want is for someone to be able to enumerate the list, you could expose an iEnumerable whose GetEnumerator function would simply call the list's GetEnumerator function.
As per the refactoring catalog its always better to encasulate the collections. This prevents some one from accidently currupting the data by adding or removing items from the list. If you don't need the functionality of protecting your data from accidental changes you can return a normal list.
By exposing the Add and Remove methods you get the advantage that any changes happens only through these methods.
Depends on the functionality you want. If you just want people to be able to manipulate the list, you could expose it through a read-only property (without the setter). If you want extra code to be executed when users manipulate the list, you should write your own methods, and not expose the list.
I have a generic list List<T> and I want to create a view that iterates the list and spits out the output.
I'm coming up against a couple of issues:
I don't know how to get my view.aspx to understand T
I don't know how to get it to render the correct partial for T
For instance, if I pass in a list of CustomObject1 then I want to render the partial CustomObject1.ascx and if I pass in a list of CustomObject2 the I want to render the partial CustomObject2.ascx.
Is there a simple way to do this that I've overlooked? I don't want to have a different aspx for every type of list I want to use, I'm just generating a of items after all. So it's a waste to have 15 different views to cover each type of list I'm going to need to use.
Any ideas or solutions would be gratefully received.
If your names are always going to match (CustomObject1 then I want to render the partial CustomObject1.ascx), then you could use the type name. So:
void MyMethod(List<T> items)
{
foreach(T item in items)
{
Html.RenderPartial(item.GetType().Name, item);
}
}
Example of Anthony's first answer: make the list contents responsible for rendering themselves by e.g.
interface IHtmlRenderable
{
void RenderHtml();
}
void MyMethod(List<T> items) //where T implements IHtmlRenderable
{
foreach(T item in items) ((IHtmlRenderable)item).RenderHtml();
}
But John's answer seems cleaner because you don't need to spend effort implementing this interface on each of your classes - or adding attributes etc.
Sounds to me that you first need to be using an Interface which is common to all your CustomObjects. Your View would then be base on List<IMyCommonInterface>.
As to including the correct ascx I'm not sure how even the generic system would solve this.
There are two approaches I can think of.
Have ICommonInterface expose a property that specifies the custom control to use. Simple but somehow feels all wrong and dirty.
Create an Attribute class that can be used to decorate the CustomObject classes, this attribute specifies the custom control to use. More complex because it requires a little reflection to discover the value of the attribute but somehow feels right and clean.
I am having asp.net page where i have combo box . I am highly confused that how to fill that combo because i am having two approach
Fetch combobox data : by creating object of my database class. and call function for combobox data.
Fetch combobox data : using static function
When should we create static function and how can we decide whether function should be static or not.
Suppose i need to fill No of people living in city based upon city Id and there is another condition of filter like business group, service group, students.
What is better approach of filling combobox.
Function should be static if it's supposed to be stateless. Simple as that.
You can have a lot of scenario how to fill your combobox.
For example:
You can derive from ComboBox and you can fill they on on Load event (or on anyone else event, if you want)
You can have classes for combobox fill with same interface (for example: UserConboBoxFiller, InvoiceComboBoxFiller, ArticleComboBoxFiller, etc...)
You can have static methods for combobox fill - as you wrote. It's not wrong, in simple scenarios.
If you have several filter conditions for filling comboboxes, I recomend use the classes for filling:
public interface IComboBoxFiller {
void Fill( ComboBox cbo );
}
public class UsersComboBoxFiller : IComboBoxFiller {
public bool OnlyOnlineUsers {get;set;}
public void Fill( ComboBox cbo ) {
// there is logic for combobox filling
// you can dynamicly generate where condition
// by the "OnlyOnlineUsers"
}
}
You make your functions static if they do not need to work on class instances and access that instance state.
Static classes and functions are of common use in web applications because these applications are mostly stateless working over stateless HTTP. Or at least they mimic statefulness by using some tricks like sessions, cookies or injecting some helper content into HTML. But even so, there is almost no state in PC memory as such - objects are created to serve the request and deleted after the response has been sent. So, classes and functions are mostly there to pack user data and sent it to the database and in reverse direction. Mostly, just dataflow processing.