简体   繁体   中英

Binding with dynamic columns to a datagrid with mvvm

So I have a WPF MVVM application with a datagrid, and I'm having some trouble setting up the datagrid. I have simplified down the model to make this easier to see the issue, but try to assume that the model can not change (unless for some reason it absolutely has to). I have an observable collection of a custom object as my item source. Let's call the object MyObject. So I have this as my datagrid's itemsource:

ObservableCollection<MyObject> myObjectCollection;

Each object contains an observable collection of another type of custom object. Let's call these new objects MyObjectElement. So each MyObject has the property:

ObservableCollection<MyObjectElement> myObjectElementCollection;

Each MyObjectElement has 3 properties:

string Name;
string Element;
bool IsField;

It can safely be assumed that each MyObject has the same number of MyObjectElements in the myObjectElementCollection, and they all have matching Name and IsField properites. I want a column for each MyObjectElement in a MyObject's myObjectElementCollection only if the IsField property is set to true. Element is the value of each cell.

Now that is the first part of the problem: getting that DataGrid to generate with support for two-way binding. The second part of this problem is the DataGrid Column Types.

I have 2 classes, MyObjectImage and MyObjectTextBox. These both inherit from MyObjectElement. The collection myObjectElementCollection in MyObject does not actually contain any MyObjectElements. It only contains MyObjectImage and MyObjectTextBox objects. If the type of of MyObjectElement is MyObjectTextBox, then it should just show the string.

However, if the type is MyObjectImage the datagrid column should show an image. MyObjectImage contains a property that is a string called ImageType. This string will always be 1 of three values: "PNG", "XAML", or "SVG". If it is equal to "PNG", it is safe to assume that Element is a base64 string of the png. If it is equal to "XAML" it is safe to assume that the image is stored as a large XAML string in Element. If it is equal to "SVG", then it is safe to assume that the image would be an svg as a string, which I do have a converter function that will turn that into a XAML string. The user would change out the image via double clicking on the cell, though that is semi-irrelevant to the problem. It is also safe to assume that the ImageType property will match with it's associated ImageTpe properties in the other myObjectElementCollections.

If you are able to input any advice to any part of this datagrid problem, that would be awesome! I've been banging my head on this for weeks! To make things a bit easier, here is some sample code of the model's structure (it is safe to assume that INotifyPropertChanged is implemented in the class ObservableObject):

My Object

public class MyObject : ObservableObject
{
    private ObservableCollection<MyObjectElement> _MyObjectElements;

    public ObservableCollection<MyObjectElement> MyObjectElements { get { return _MyObjectElements; } set { if (_MyObjectElements!= value) { _MyObjectElements= value; RaisePropertyChanged("MyObjectElements"); } } }
}

MyObjectElement

public class MyObjectElement : ObservableObject
{
    private string _Name;
    private string _Element;
    private bool _IsField;

    public string Name { get { return _Name; } set { if (_Name != value) { _Name = value; RaisePropertyChanged("Name"); } } }
    public string Element { get { return _Element; } set { if (_Element != value) { _Element = value; RaisePropertyChanged("Element"); } } }
    public bool IsField { get { return _IsField; } set { if (_IsField != value) { _IsField = value; RaisePropertyChanged("IsField"); } } }
}

MyObjectImage

public class MyObjectImage : MyObjectElement
{
    private string _ImageType;

    public MyObjectImage() : base()
    {
    }

    public MyObjectImage(string name, string element, string imageType) : base(name, element)
    {
        ImageType = imageType;
    }

    public string ImageType { get { return _ImageType; } set { if (_ImageType != value) { _ImageType = value; RaisePropertyChanged("ImageType"); } } }
}

MyObjectTextBox

public class MyObjectTextBox : MyObjectElement
{
    public MyObjectTextBox() : base()
    {
    }

    public MyObjectTextBox(string name, string element) : base(name, element)
    {
    }
}

Again, any and all help is appreciated with this problem; Thank you!

I was able to accomplish the first part of the problem through a method that can be found here . The second part of this problem should be able to be accomplished through templating the incoming items.I can easily create an image property that does a conversion to a bitmap image from any of those as the display for the datagrid column.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM