C# class with dynamic properties - c#

I have a class that I will be using to bind to a grid. The grid columns will correspond to the public properties of my class, all of which are decimal?.
Right now, in order to display all of the required info, my class includes around 30 properties. I created these properties based off of a list that might change in the future.
It seems that hard-coding the properties and updating the class after any change is not the right way to do this but I am not sure how to create "properties" at run time (I have access to the list) and have them bind to the grid (Infragistics xamDataGrid in this case).
Any suggestions on what I can use?

ExpandoObjects allow dynamic assignment of properties (which are even bindable as the class implements INotifyPropertyChanged), if that helps. They are slower though in terms of performance.

Related

Displaying ListviewItem Properties In Grid Columns

So I've added a bunch of items to a ListView. All of the items added are structures that have 4 members. The members are Amount, Location, Date_Time, and Category. These members are setup as properties and I was trying to bind each member to a column in the ListView.
Unfortunately, my results are blank entries or the added structures ".tostring()" return value. Essentially I have no Idea how to correctly setup up the binding. Any ideas in XAML or C# would be appreciated. Also the structure resides in a separate class, not the MainWindow class that contains all the controls. Formatting and styling is still in the works for my listview so don't judge my bad color scheme.
Thanks
Don't use images to show us your code. StackOverflow allows to insert code snippets. Also use paragraphs to format your question. Always see on your question after you've posted it.
Binding works only with public properties. Change access modifier of your structure and its properties from internal to public. See answer at this topic.

Dynamically change XAML binding based on type

I have a list of objects that is being used as the source for a DataGrid. This list of objects is a base class type, of which there are 2 or more inherited types. I am trying to bind to properties of the base class to display as values in the columns of the DataGrid. The subclasses have different properties available to them which I would like to be able to display, so my question is, does XAML have a way to dynamically change the value of a binding based on the type that is being pointed to? I have thought about potentially doing this with a converter, but if I understand correctly, then I would have to write a different converter for each subclass property that I need to bind to. Any advice or suggestions are appreciated. Thanks
This is probably possible, with attributes and some reflection you could mark the properties that should go in the various columns and then auto-generate those. You could also create a sparse grid, with columns for all possible properties; this should also be possible via reflection and does not require any additional metadata.
(You can auto-create the columns based on the items using an attached property (like this) if the native DataGrid event is not sufficient for this.)
You can define multiple DataTemplates and specify the intended type through the DataType property. The correct template will be selected depending on the type of the bound object.
https://msdn.microsoft.com/en-us/library/system.windows.datatemplate.datatype(v=vs.110).aspx
The means to achieve this would be a CellTemplateSelector.
See this link.

Best Way to Override ComboBox.Items

I've created an owner-draw user control that inherits from ComboBox.
The control stores specialized items, but the Items collection still accepts and returns items of type Object. Any tips on the best way to override this collection to be type-safe?
About the only way I can think of is to create my own collection class. The class wouldn't be a true collection--it would take an ObjectCollection as an argument to the constructor and simply extend the methods of that to.
The user control would pass the original Items collection to the constructor of the new class. And then override the Items property to return an instance of the new class instead.
This seems somewhat convoluted. Is there a better way?
You could do it a couple of different ways. First off, I'm a little confused about you creating a "user control" that inherits from ComboBox. You can create a custom control that inherits from ComboBox, but you cannot inherit from both UserControl (which is the usual definition of a "user control") and ComboBox.
If you define a true UserControl derivative, this gets a little easier. A UserControl, like I said, can't be a ComboBox, but it can have a ComboBox. So, you can drop and Dock a ComboBox to your UserControl surface, and then re-implement any properties you need to be able to use, such as Items. This will allow you to re-create Items as a collection of your choice, probably a strongly-typed List. The only problem will be knowing exactly what you'll want to re-implement; there's a lot of useful properties of a ComboBox that you won't be able to access in the Designer or in code unless you implement a "pass-through" property that modified the contained ComboBox within your UserControl.
If you inherit directly from ComboBox, it gets a little tricker in some ways, easier in others. You can hide the base class implementation of Items by defining your own and using the new keyword. You can change the visibility, type and other modifiers when you do this. This will prevent code that deals with your control as a CustomComboBox (or whatever you name it) from using the object array on the base class; they have to use your strongly-typed Items array. Your new property can still access the old one (which it will need to in order to make it work). You also get all the other public properties of a ComboBox for free; you only have to reimplement what you want to change. However, referring to your custom ComboBox as any base class will cause the runtime to use the version of Items that is valid for that class; that is, the object array, not your strongly-typed one.

How to implement a Properties window style control/system in Windows Forms?

So what I am trying to do is to have a set UI with certain controls, and I want to have some class instance to fill in the values.
For instance:
Classes that can populate the UI:
Sharpen, Blur, Smear, ... : FilterBase
So whenever the user creates an instances of the above classes, I want to automatically fetch the values based on the UI controls, by using the class instance.
The UI has items like:
.Name (TextBox)
.Amount (NumericUpDown)
.Decay (NumericUpDown)
So if the current instance is s = new Sharpen(), I want to get s.Name to fill out UI.Name.
How do I do this in the best possible way? Elegancy, clarity, performance wise, etc.
I am gonna use reflection, but how do I store the instance of the object (Sharpen, ...) and be type safe? Should I use an System.Object instead? Or T?
public partial class ParamsUI
{
T CurrentFilter (?)
...
}
Also if I use T, how will I know what to cast it to?
Is there a better way?
Since this is using Windows Forms, the most flexible option would probably be to just use the Windows Forms PropertyGrid directly.
You can do a lot of work to customize the look and feel of this. See Getting the Most Out of the .NET Framework PropertyGrid Control for details.
Edit:
If you want to have a very flexible, easy option, and WPF is an option (hosted within an ElementHost), you could consider using WPF.
With this, you could host a UserControl containing nothing but a resource dictionary and a ContentControl.
You could then make a custom XAML file for each item you want to edit, and setup a data template in the resources specifying the mapping of which user control (xaml) to use for each element you want to edit. You can then just set the element to the user control's "DataContext" in code, and it will automatically wire everything up and "just work".

WPF check if a dataproperty has an binding

Hej,
I'm trying to make som general functionality for my ListView, so that the content of a ListView can be exported to CSV directly.
I'm trying to achive this by getting the datacontext and analysing the ICollectionView for this. From here I have access to the all the objects from via ICollectionView via SourceCollection, in which I (for now) presume sorting/and filtering is respected.
The challange here is that I only want to output the columns that also are showed in the ListView.
When iterating my collection, is there a function where I can evluate if a property in a class (with notification suppoert) has a binding to it?
The esiest solution for now would be just to output all properties, but I'm not interested in this, since oid's are not fun to look at.
Thx in advanced.
/Ian
I suggest you recognize that the ability to determine which data is being displayed is a business requirement. Thus, you should embody this requirement in your model. In other words, your model should clearly indicate which columns are visible - you shouldn't be trying to infer this from your existing properties, nor should you be examining your view.
There are a whole bunch of ways you could do this, but the key is to have this information on hand in your model.
Why don't you just look at the DataTemplate and evaluate it including the binding inside?
There's no easy way to do it... You can check the binding on the target side (dependency property), but not on the source side.
For what you're trying to do, you could loop through the columns of the ListView and check their DisplayMemberBinding, but it could be undefined (the cell content might be defined using the CellTemplate property instead).

Categories