Passing objects to a UITypeEditor - c#

I am currently hoping to use a PropertyGrid to allow users to edit some of my classes, however I've hit a wall with passing objects to the UITypeEditor(s) they use. When the user presses the drop down I want to show a listbox of already loaded textures to choose from, if they want to use a texture the application hasn't loaded yet they can click a button to choose one from a file dialog. In case I make no sense here a mock of the form:
.
My problem: To fill the listbox I need access to the class that manages the list of resources from the UITypeEditor.
Now I've solved this problem for my own classes by giving them a reference on creation to their managing object. In the UITypeEditor I then use that reference to access what I need. However I can't do this for classes I haven't written, such as the XNA Texture2D class.
Here are what the classes I'm using look like:
class StaticGeometryChunk
{
// Geometry data to draw with. Contains a reference to its managing
// class for use in its UITypeEditor.
public GeometryData { get; set; }
....
}
class Material
{
// These are XNA classes. I can't just add a reference to its managing
// class (I think?).
public Texture2D Texture1 { get; set; }
public Texture2D Texture2 { get; set; }
....
}
I've been looking at my options and they seem to be:
Make the managing classes static.
I don't really want to do this. There are several managing classes as each resource is loaded differently. There are also classes that need to be created before these and are passed in.
Make the managing classes singletons.
I don't really want to do this either. It seems like a quick and dirty way to "hide" the problem instead of "solve" it. I also might want the option of having several managing classes in the future which the singletons eliminate.
Create a wrapper class which holds the reference to a managing class and its target (such as the XNA Texture2D).
This is currently what I'm thinking of doing. Its would be quite simple and quick to do but something about it nags me but I don't know what.
Any thoughts on the above or other methods to pass what I need into the UITypeEditor?
Thank you for reading.

In the EditValue method, you are given a context. Use context.Instance to access the object that holds your property. This object should also contain a property that gives you access to the list of things you want to display. You could test if context.Instance is ITextureProvider for example, then cast it and access the textures. Not sure if this makes sense in your design but let me know.

As an alternative you can try the following approach. I find it very elegant, because it does not require to store a list of available property values in the object. Therefore, for example, you can show one set of values on one form and another set on another.
Create an interface IYourDataProviderService.
Create an implementation of IYourDataProviderService, which knows the concrete data to provide.
Create a class implementing ISite. In GetService() method return an instance of class which implements IYourDataProviderService, if the serviceType parameter is typeof(IYourDataProviderService).
I left rest of ISite methods throwing NotImplementedException (except DesignMode property) and for me it worked, but probably this is not an ideal solution.
In 'Load' event handler assign your implementation to the Site property of your propertygrid.
Enjoy!

Related

How to access variables in a class from all forms

I have a few forms, and a class Management which has a list of users, info and stuff. I want an instace of Management which I will be able to access from all the forms. How do I do that?
Thenx in advance.
The error
Error 3 Inconsistent accessibility: parameter type 'ProjectClasses.Management' is less accessible than method 'FinaleSystem.MenuForm.Start(ProjectClasses.Management)'
means that your MenuForm is exporting a method Start (probably it is public) having a parameter of type ProjectClasses.Management that is less accessible. Probably it is internal. Declaring the Management class as public will resolve your problem. If the class is nested within another class, declare the "parent" class as public as well. If you prefer not to make the class public, make the method Start internal instead.
public means that an item is accessible from another project. internal means that the item is only accessible within the same project. If Start was public and the type of a parameter internal or private you could not call the method from another project, since you could not create an object of the requested type. You couldn't derive a class from it either in order to use it as a parameter.
Non-nested classes have a default access modifier of internal. Nested classes have a default access modifier of private.
See https://stackoverflow.com/a/3763638/880990 for details
Best way (my point of view) is to use a MVVM pattern and have the ViewModels inherit from a base class
Just to elaborate on Thomas' answer.
Singleton
A singleton is basically a class where it only ever allows the program to holds one instance of itself. In other words, whether you're in the Superman class or the Batman class, the Singleton class, let's call it MyCar will always be the same.
A Singleton is pretty easy to implement and to grasp. Take a look at this tutorial: http://www.usmaanz.com/singleton/ to get an idea.
MVVM
A MVVM pattern is pretty powerful! It allows you to create an object which contains certain amount of properties and allow that model to be used by many Views or Forms in your case.
Let's say that a Form has the following controls:
Username
Password
Email
And in this form, we wish to hold data from what is being passed in to these controls. Therefore, the following class will help us hold that data:
public class MyModel
{
public string Name {get;set;}
public string Password {get;set;}
public string Email {get;set;}
}
Then in your Form, you may do:
MyModel model = new MyModel(){Name = txtName.Text, Password = txtPassword.Text, Email = txtEmail.txt};
This object will now hold the data of the form. You may also use this class to hold data any where else and you can obviously, freely, create as many instances of it as you want.
Hope that helps!
One possible solution is to make your Management class' properties static.
Cheers
The simple case of this is implemented as a singleton where one and only one instance of a class exists for the life of the program. Singleton has many drawbacks mostly related to difficulty of testing and correctly handling threading. The next pass at solving this is usually implemented as a service locator pattern, however this has also come to be viewed as an anti-pattern. The best way to handle this is called dependency injection. While DI is the "best way" it may be hard/over kill in your scenario.

"static" instance of a class for each instance of a custom control

I have a custom control. This custom control uses Reflection heavily. Inside the custom control assembly I have a class, which is a reflection manager. It handels everything reflection related in the control. One of the things it does is cache the PropertyInfo objects for each property of the objects in the DataSource. I would like to make it static so I can easily use it inside the custom control class and also other support classes inside the assembly. The problem is that this control is used in several places, and with different datasources, and each has it's own collection of PropertyInfo objects.
What would be the best way to create this class so that it has an instance per instance of the control, and is also available to other classes within the custom control assembly.
One thing I thought of is to insert the instance of the reflection manager I created in the custom control class in to a property / though the constructor of the supporting classes (ala DI), but maybe there is a better pattern I'm just not aware of.
Edit: Sorry for being unclear. The project is an ASP.NET WebForms project. The control is a CompositeDataBoundControl if that matters.
Edit 2: I will elaborate on the design I have and what flaws I see in it.
I have a custom control class which is being used (or planned to be used in several pages).
Inside this control I have this class (sorry if I have some syntax mistakes, I`m writing this from memory). This is not the entire class, just what is relevant here.
public static class DataReflectionManager
{
private static Dictionary<string, PropertyInfo> _propertyInfos = new Dictionary<string, PropertyInfo>();
public static void RegisterDataSource(IEnumerable dataSource)
{
//Get the property info of each property of and
//stick it in the dictionary.
}
public static string GetValueByPropertyKey(object o, string key)
{
//Takes o and gets the value of property key by the PropertyInfo object.
return "";
}
}
Now this class cannot remain static, or the dictionary will be the same for all instances of the custom controls, and they each have their own datasource, which holds different types of objects. So... static is out. But what then?
If I used DataReflectionManager in just the custom control class, I would just create an instance there. The problem is that the custom control uses column types, which all inherit from ColumnBase and ColumnBase has an abstract function, which uses the DataReflection manager in most of the inheriting column types. So I could pass the instance around, but I'm looking for maybe a more intelligent solution.
Since you can't have multiple instances of static classes, I would solve this by adding a static Dictionary<> keyed by the control class name that holds control-specific instances of the reflection manager.
I could not find a "perfect" solution here, since every way of doing this I could come up with has some drawbacks for our specific design.
The thinking that helped me arrive at my current solution was that the list of ProperyInfo objects is tied to a specific instance of the control, and thus the Dictionary<string, PropertyInfo> used to store it should also be a member of the control class. This allowed me to keep the reflection manager static and make minimal code changes in supporting classes.
Supporting classes get PropertyInfo objects as needed in their respective constructors.
The reflection manager created the dictionary through reflection in the control constructor and from there on, the control stores it.

Decorator Pattern vs Inheritance with examples

I've been experimenting with the decorator pattern to extend functionality of code you do not want to touch for example and I see how to implement it however I am now unsure why you don't just inherit from the original class and extend that way.
I have read that the decorator pattern allows you to add functionality at runtime whereas inheritance means its there at compile time.
I don't understand this.
Could someone explain this, provide examples and explain when its better to use decorator vs inheritance.
Thanks
Suppose you create a View class that displays your items in a certain way.
Now you decide you also want a version of it which is scrollable, so you create a ScrollableView which inherits the View.
Later you decide you also want a version with a border so you now need to make a BorderedView and a BorderdScrollableView.
If on the other hand you could make a decorator for each added styling. You would have the following classes:
View
ScrollableDecorator
BorderedDecorator
When you want a bordered scroll view you do:
new BorderedDecorator(new ScrollableDecorator(new View())).
So you can configure any combination of this with just the 3 classes. And you can add or remove them at runtime (suppose you click a button that says add border, you now wrap your view with a BorderDecorator ... while whith inheritance you need to implemented this view class if you haven't already, or you need to create a new view instance and copy all relevant data from the first view to the second view which is not as easy to do as just adding or removing wrappers).
Imagine a game like Civilization, where each square on the map can have a variety of resources attached to it (like, say, various ores, or wood, or oil, etc.).
If you used straight inheritance, you'd need to create a class for each kind of square. It'd be unwieldy to have
public class OilSquare {}
public class OilAndGoldSquare {}
public class GoldAndSilverSquare {}
// etc.
The Decorator Pattern allows one to mix and match without needing to create a rigid hierarchy. So, you'd have instead:
public class Square {}
public class GoldDec {}
public class SilverDec {}
public class OilDec {}
// ...
var crazyMix = new GoldDec(new SilverDec(new OilDec(new Square())));
Put another way, Decorators allow for the creation of pipeline behavior, with each step in the pipeline being swappable with another step.
As others have already said Decorators are good for adding "options" to things... The benefits come in the way you can chain methods etc. through the decorators.
Imagine I buy a car with options for leather interior, metallic paint and awesome spoiler...
There are 8 different combinations of the three options but with decorators you only need three extra classes.
The interesting thing though is the way the decorator pattern works. As a brief example:
public class MetallicPaint : Car
{
private Car car;
public MetallicPaint(Car wrappedCar)
{
car = wrappedCar;
}
public decimal Cost()
{
return car.Cost() + 500;
}
public string Description()
{
return car.Description() + ", Metallic Paint";
}
public string Speed()
{
return car.Speed();
}
[... {pass through other methods and properties to the car object}]
}
This isn't a complete example but highlights how the decorator can interact with the object it is decorating. And of course because it implements car it can be used just like a car in every other way (and passes through anything the decorator doesn't effect to the inner car object).
Of course if you had multiple of these decorators with a car nested inside each would in turn add their cost, their part of the description and maybe the spoiler would alter the speed whereas the others didn't...
In essence it allows you to modify an object in a much more modular and less fundamental way than inheritance would. Decorators should always be used as if they were the base object (in this case Car) so they should never expose any new methods or properties, just slightly change the effect of existing ones.
Decorator pattern is better than inheritance if you have many features to be added and you also require to have combination of these features. Suppose your base class is A, and you want to extend(decorate) this base class with feature f1,f2,f3,f4 and some combination of them like (f1,f2) and (f1,f3) and .. ; so you would require to create 4!=4*3*2*1=24 class in your hierarchy (4 for each feature and the rest for their combination). While, Using decorative pattern, you would only need to create 4 classes!
for #Seyed Morteza Mousavi in #Razvi post:
You are right, we can add two properties Scrollable and Bordered to View class, then check if the property is set to true so run the desired behaviour. But this requires that we already be aware of the number of the feature we require(which is not the case in decorator pattern). otherwise, with every new feature (say f1) we want to add to our class, we need to alter our main class, or inherit the main class (you would say) and add the property. Taking latter approach, you would further need to alter the part of the code which handles feature combination (this is not good, since it is not obeying the rule of thumb of "loose coupling!")
hope this helps.

How would I create composite settings for an application?

What I would like to do is have a versatile settings class that I can use in a composite application. As I add features and components and compose the application using MEF & Prism I would like to have a settings window that automatically loads the settings interface of each of the modules into a window (using Prism & MEF)
There are many different ways of dealing with settings, and the one that appeals to me is something along the following:
public class AppData : ApplicationSettingsBase
{
[UserScopedSetting()]
[DefaultSettingValue("true")]
public bool Clipboard
{
get { return ((bool)this["Clipboard"]); }
set { this["Clipboard"] = (bool)value; }
}
}
It allows me to set a default value and I am assuming that if the application does not find the .settings file then it will create one with the defaults. However I would need to write a bunch of custom code for each modules settings section and either create a unique dialog for each module or try to have a settings manager that manually loads them all in.
There are some settings that would have multiple values as well and it does not look like the above example would be able to accomodate that. What if I had a setting that stored a list of something? For example if I had a setting that was ValidBlock, and at the start there are two blocks that could be valid but in the future there may be a need to add more? Can you have a setting that is a list and specify multiple default values for that setting?
So would it be acceptable to create a Isettings interface that somehow used ApplicationSettingsBase so that I can use MEF to find all Isettings implementations in all the modules in a directory and then compose a dialog with tabs for each implementation it found? In the Isettings interface I could have some basic properties such as Name and whatever else would be needed to label and describe the module in the MEF WPF window.
The only other thing I do not like is that there are strings and attributes all over the place. Is there a way to deal with settings in a fluent way? I am thinking along the lines of having a ISettings implementation that you would explicitly code a setup something like the following:
public class AppData : ISettings
{
Setting Clipboard = new Setting();
Clipboard.Scope = SettingScope.User;
Clipboard.SettingType = List<String>;
List<String> DefaultClipboards = new List<String>();
DefaultClipboards.Add("FoxClipboard");
Clipboard.DefaultSetting = DefaultClipboards;
}
I know the above is not exactly syntax correct, and I do not think that the Clipboard.SettingType would hold much water but its to give an idea of what I am thinking. So if something like this can be achieved while maintaining the creation of a settings file in the event one is missing that would be ideal. As well with something like this MEF can find all the ISettings implementations and create a tab for each one, and then add each Setting based on setup of it in the code.
Is this the right track to be on? Is there a framework or project out there that I have missed that handles what I am aiming for? I am thinking there is probably a better way than what I have outlined?
I am sure this question has come up in composite application development but I have not found a framework or an answer that outlines this scenario.
I have been able to create a loose coupled composite application and dynamically wire up my modules using MEF & Prism but I have not been able to find a satisfactory way to deal with settings in a composite way.
I tackled something similar for one of my applications at work. We leaned further towards your second idea, where there is simply a base settings interface "ISettings" that we used for MEF composition.
We created a custom export provider to deal with loading settings, and had a manager to save out the settings using some serializer.
For the UI, we had modules with user facing settings also export a "settings workspace" that we would load into the settings UI. Using reflection, we wrote a method that will make a deep copy of a settings object so that we could do direct mvvm binding to the cloned object (for cancel functionality), as well as take an object and copy it's properties back.
The reflection was to allow for a generic clone/copy without writing code for every settings object.
Also, one thing that we did that I still love to this day for data model binding is the "INotifyPropertyChanged" interface. Our base ISettings object requires it. This allows not only the settings UI to directly bind to settings and listen for changes, but when we hit apply or ok, all of our data model that needs settings registers for the prop changed event, so they all automatically get notified when a setting has changed.
Check out Property Observer if you plan on doing the notify route. This application has been deployed and I still feel like our settings framework is wildly successful.
If you need, I can provide further detail in certain areas.
Hope this helps!
Disclaimer: I have no experience with custom implementations of ApplicationSettingsBase so I can not assist with its actual implementation, nor positively say that this approach will work. However, what I propose might be a path worth exploring if you really want to use ApplicationSettingsBase.
First of all, ISettings can not inherit ApplicationSettingsBase, because interfaces can only inherit other interfaces.
My proposal is to create a custom ApplicationSettingsBase implementation that is parameterized with an instance of ISettings. That way, whenever you recieve an ISettings from your components, you instantiate a new CustomAppSettings (see below) and associate that with your component.
Since ApplicationSettingsBase uses a string-to-object key value pair mapping, I propose an interface that does the same.
public interface ISettings
{
Dictionary<string,object> Values{ get; set; }
public object GetDefaultValue(string key);
// Whatever else you might need
}
public class CustomAppSettings : ApplicationSettingsBase
{
public ISettings Settings { get; set; }
public override object this[string propertyName]
{
get
{
return this.Settings.Values[propertyName];
}
set
{
this.Settings.Values[propertyName] = value;
}
}
// There will be more implementation work for this class I'm sure
}
In addition you would need a serialization mechanism for your ISetting instances.
Edit: Fixed some code syntax errors

Singleton rule questions (do not allow to create copy and deserialization)

Reading some article about singleton, I stopped at the point saying: "Do not allow to crate copy of existing instance".
I realized that I do not know how would I do that! Could you tell me, please, how could I copy existing instance of class?
And the second one: deserializaition. How it could be dangerous?
And for both - how to deny creating copies or deserialization?
Thanks
There are objects with something like a Clone or a Copy method. The idea behind it that it will take the current values of the object and make a new one. The defeats the purpose of a singleton object, because suddenly someone can create a second copy of it.
Another possible way of creating a copy of the object, would be to serialize the object and then de-serialize it to create another copy. So you probably want to mark the singleton object as not serializable.
Using serialization/deserialization, you could store the object somewhere and then restore it. That way, you will have two objects. Any changes made to the singleton in the meantime would not be reflected in your new copy.
Afterwards, when you now try to get/set something using the singleton object, you might change it in/get it from the one object or the other. Obviously that can cause all sorts of (sometimes very hard to debug) problems.
EDIT: To create a singleton in C#, see the explanation at http://www.yoda.arachsys.com/csharp/singleton.html
As for serialization: You have to explicitely enable it by including the SerializableAttribute. So simply don't mark your class with it. Note that there is no NonSerializableAttribute for classes, only for fields. It is used when you enabled serialization, but want to deny it for certain parts of the class.
EDIT2: To deny XML-serialization, you could implement IXmlSerializable on the class. Then simply either have empty implementations or throw exceptions from the member methods.
As has already been mentioned:
You don't want to make a singleton serializable or copy/clone-able because then you can make more than one object, which defeats the purpose of the singleton.
To prevent serialization in c# is easy - don't mark the class as [Serializable]
To prevent copying/cloning of your singleton you could try changing it to a static class so that can't be instantiated (in the normal way) if that's practical. I'm not sure if the class is technically a singleton any more then.
Another way (probably better) is detailed in Item 13 of Bill Wagner's Effective C#. i.e. using a static constructor and making your singleton a read only property of your static class.
Example:
public class SingletonExample
{
private static readonly SingletonExample singleInstance
static SingletonExample()
{
singleInstance = new SingletonExample();
}
public static SingletonExample Instance
{
get { return singleInstance; }
}
private SingletonExample()
{
}
}
There are a few things to look out for, like Kevin mentioned any sort of .Clone() or .Copy() methods. If your building the class your self, then be carful with the .MemberwiseClone() method as it will make shallow copies of the object.
As far as serialization. Preventing general serialization can be done by not tagging [SerializableAttribute()] to you class. I'm not sure there is a way to prevent XmlSerialzation, directly. But there are a few things you could do to prevent this if your building the class.
If you're building the class, and you do not provide a default constructor then the XmlDeserializer will not work as it uses the default constructor to rebuild the object. I belive this funcitonality has changed in 4.0 however, so you may want to look more into that. Using the [XmlIgnore] Attribute on yoru fields and properties will render the serialzation useless as well.
The important part here is that the person trying to do this understand it shouldn't be done, not that it can't. If someone really wants to do serialization/deserialization on your class, then you can't stop all avenues as he can implement his own serialzation/deserialization of your object. Also serialzation of singletons is sometimes intended such as the cases of application settings or custom settings. The intent is to inform somehow the person trying to serialize/deserialize not to do so.

Categories