C# Generic Data Abstraction - c#

So essentially I'm making a WPF/MVVM Light application and I currently have a TreeView that represents a variety of different types of objects. Each of these objects is wrapped in a very generic "ViewModel" that currently just exposes their name to the TreeView display in the application.
Linked conceptually to this tree, I want to provide an Object Viewer below the tree, such that when a user selects an item in the three, the object viewer is populated with the Properties of that node and it allows the user to change and save new values to the node in question.
I'm effectively trying to create an abstraction that can take a variety of types (7 different object types) and expose their Properties AND allow the user to edit them. Essentially, I can bind the properties of this abstraction to a group of Text/Display boxes on the UI, and when the user hits save, have it call update methods on the actual underlying data objects from this middle wrapper class.
Currently, the only way I can think to accomplish this is to make a separate wrapper for each underlying object type (since they all have different Properties), and essentially hard-code the fields and update methods.
Are there any other options in terms of providing further abstraction and creating a general wrapper class capable of exposing and updating Properties from a variety of objects? Thanks.

Instead of wrapping every model in a different ViewModel, you may want to expose the model directly to the View and create a DataTemplate for each type of model, this will allow you to have different UIs for each model type without having to place an intermediate ViewModel in between. Just a suggestion.

Related

C# - Can a Method Examine Another Method's Use of a Parameter?

I have a variety of methods that use a configuration object to fill in placeholders in a template. Different methods use different subsets of properties of the configuration object. I'd like an easy way to check that all the properties a given method uses are present in a given config object.
Right now I have a method like this:
private static void ValidateConfiguration(CustomerConfiguration config, params string[] properties)
This has the maintenance disadvantage that it relies on a separate set of strings for the properties used. What I'd love to do is have the validation method look at the calling method and see what properties of the config object are being accessed. Can this be done?
(I could also wrap String.Replace() in a method that checks for nulls, but that's less fun.)
A type safe way to handle your problem would be to implement several interfaces with different meaningful subsets of properties. My understanding is that the presence/absence of the properties in your case depends on the type of configuration object and is dynamic.
you could use a signature like that
ValidateConfiguration<T>(CustomerConfiguration config)
where T represent the interface and use reflection to list the required properties. While it would be practically impossible to parse the code of a method to infer its usages of a data structure, reflection on types (to extract properties) is fairly easy.
Different methods use different subsets of properties of the configuration object.
If you're only creating one instance of the configuration property, then the properties it needs to have are whichever ones are going to be used by any method. In other words, if at least one method needs that property, then the object needs that property.
In that case there's no need to validate it in relation to individual methods that need it. All of its properties need to be populated because they're all needed somewhere. If they're not needed anywhere, you can delete them.
Then, instead of validating that object based on the needs of a particular method, you validate it once, perhaps at startup. All of the properties are needed, so if they haven't been specified then the application just can't run. (Sometimes it's good to include defaults in your configuration object. You might have one property that you want to be able to configure, but in real life it's never going to change.)
If you're creating different instances of the same object for use in different methods and you only want to populate certain properties then it's better not to do that. Just create more granular objects for different scenarios containing all the properties you need.
What frequently happens is this: We have an object with lots of properties and we only use a few of them, so we populate those properties and pass the object to a method. The other properties are null.
Then, someone modifying that method decides that they need another property, so they try to use it, and they're surprised to find out that it's null. Then they have to go back and trace where that object was created and figure out what is populated or not. That's confusing and time-consuming.
Unless fields are entirely optional and it doesn't matter whether they are populated or not, we don't want to find ourselves looking at an object with lots of properties and guessing which ones have been populated because individual methods that create the object "know" which properties other classes do or don't need.

Where Do You Store Data in a GUI Application?

I've always heard that you should separate GUI/Data/Logic components, like the MVC pattern.
So, I am wondering: In a GUI application, where do you actually store the data?
Here is an example (using C# terminology):
Suppose you have a GUI that takes user input, does some analysis, and displays results in a table. The user can have several analyses in one window, so there is a ListView at the bottom that allows the user to select which analysis is currently displayed (the selected item gets displayed).
In order to display this, the analysis data must be stored somewhere. I have always done one of two things:
Put all the data into a single object and store it in the ListViewItem's "Tag" property
Extend "ListViewItem" and just add whatever properties I need.
But, this means I am storing the data inside of the ListViewItem.
Is there a more appropriate place to keep track of the data?
I could add it as private members to the main form, but that seems like the same thing.
The only other thing I can think of is to make some global class that I can reference whenver I need to.
Thanks.
As I understand, you have some ListViewItems. Each ListViewItem is associated with your business logic object and after select one of ListViewItem you want make some operations over this buisness object. In similar situations I usually make Data Object like
struct MyDataObject
{
string Id;//very often data object need to have Identifcator, but not always
//some fields
}
and add to data object constructors for typical user input.
After that I make business logic layer contains available algorithms for this data objects. For simple projects, this is a static class like
static class MyDataObjectOperationService{
void MakeSomething(MyDataObject myDataObject);
object GetSomething(MyDataObject myDataObject);
...
}
For big projects that is usually interface. Also I usually make a data layer interface for getting this data object. For example
interface IMyDataObjectRepository{
IList<MyDataObject> GetAll();
MyDataObject GetById(string id);
//CRUD operations if it need
}
After that I put into ListViewItems ids of Data Objects and on ListViewItemClick getting selecting id, after that getting DataObject by Id using data layer classes and make some operations using business logic layer classes. If I need to save DataObject changes or create new DataObject I using data layer classes.

Design strategies to generalize control

I have a GUI control that I need to generalize so it can be used in different situations and I need suggestions. Let me give you some background first. I have a model that stores all my data for a specific application. I access and set the data points through properties in this model.
Right now I am passing the instance of the model to the GUI control and there the client can set/reset/read in the control two specific pieces of data (in the code I am using the properties). That is all good, but now the model has 3 more sets of these two "columns" (six new fields) that also need to be manipulated by the same control in other 3 new different situations. Obviously I don't want to create 3 more copies of this same control (yes, extensibility was not considered when the control was first designed, I know, I know). So, I tried passing a reference to the properties in the control constructor which of course does not work (compiler error: A property, indexer or dynamic member access may not be passed as an out or ref parameter). So, my question is, what would be a good design strategy in this case? How can I generalize this control so it can be reused and it can set/edit these other properties in the model?
Thanks!

3 layer architechture and little details like dropdown lists

So I am refactoring a little application as an example to get more practice. The purpose of the application (let's say) is to collect the data from a "sign up new user" form, save it in the database. The only limitation I have is I have to use a special custom Data Access class which communicates directly with the database and returns the data (if applicable) in a DataTable object.
I have a question regarding a little details on a form and how do they fit in into the layer architecture. For example, my form has a drop down list that's fed from the database, but at the same time drop down list doesn't represent an object per SE (unlike a User that is a object, there is a class User that has multiple methods, data members etc). I don't want to have calls to the stored procedure right there in the code behind but I also do not wish to overdo on abstraction.
What would be an elegant way to take care of these little details w/o creating a class abstraction galore.
Hope I am being clear
Funny you should ask that. I went through that issue here.
These other Stack Overflow Questions that I've answered that show other parts (tangentially related):
Getting ListView Data Items from Objects
Working with ListViews
Concatenating Properties in a DropDownList
An option for getting non-object data to the UI is to create one or more lookup classes that are a bucket or "service" for getting odd bits of data for things like drop down lists etc...
Example:
myDDL.DataSource = Lookup.GetAllCountries(); // GetAllCountries is a static method
// set name/value fields etc...
myDDL.DataBind();
Using this methodology, you can still support tier separation. It's not object oriented or elegant, but it is very practical.
I don't know what's best practice, but what I do is I have a utility class that has a method that takes as arguments a DropDownList object and an enum, so I do
FillDropDown( ddlistPhoneType, DropDownTypes.PhoneTypes );
The utility class fills the dropdowns sometimes from the database, other times from XML, and occasionally some hardcoded values. But at least the GUI doesn't have to worry about that.

Creating objects driven by the database to populate a Treeview - very slow

I have an application that reads a table from a database.
I issue an SQL query to get a result set, based on a unique string value I glean from the results, I use a case/switch statement to generate certain objects (they inherit TreeNode BTW). These created objects get shunted into a Dictionary object to be used later.
Whilst generating these objects I use some of the values from the result set to populate values in the object via the setters.
I query the Dictionary to return a particular object type and use it to populate a treeview. However it is not possible to populate 2 objects of the same type in a treeview from the Dictionary object (you get a runtime error - which escapes me at the moment, something to with referencing the same object). So what I have to do is use a memberwiseClone and implement IClonable to get around this.
Am I doing this right? Is there a better way - because I think this is causing my program to be real slow at this point. At the very least I think its a bit clunky - any advice from people who know more than me - greatly appreciated.
Is there a reason you are using the external dictionary? I would populate the tree directly as the data is queried.
If you do require the dictionary, you could set the .Tag property of the tree node to point to the data in your dictionary.
To add to #Brad, only populate the tree as needed. That means hooking into the expand event of the tree nodes. This is similar to how Windows Explorer functions when dealing with network shares.
There should be 1 TreeNode object per actual tree node in the tree - don't try to reuse the things. You may either associate them with your data using the Tag property (this is the recommended method), or you can subclass the TreeNode itself (this is the Java method, but used less in .NET).
(The use of cloning methods is usually a hint that you're either (a) doing something wrong, or (b) need to factor your domain model to separate mutable objects from immutable.)
have you considered using a Virtual Tree view which only loads the nodes the user actually wants to look at - i've had good success with the component from www.infralution.com

Categories