使用mvvm将动态列绑定到数据网格(Binding with dynamic columns to a datagrid with mvvm)

编程入门 行业动态 更新时间:2024-10-25 08:17:11
使用mvvm将动态列绑定到数据网格(Binding with dynamic columns to a datagrid with mvvm)

所以我有一个数据网格的WPF MVVM应用程序,并且在设置数据网格时遇到了一些麻烦。 我简化了模型,使其更容易看到问题,但试着假设模型不能改变(除非出于某种原因,它绝对必须)。 我有一个可观察的自定义对象集合作为我的项目源。 我们来调用MyObject对象。 所以我有这个作为我的datagrid的itemsource:

ObservableCollection<MyObject> myObjectCollection;

每个对象都包含另一种类型的自定义对象的可观察集合。 我们来调用这些新对象MyObjectElement。 所以每个MyObject都有这个属性:

ObservableCollection<MyObjectElement> myObjectElementCollection;

每个MyObjectElement有3个属性:

string Name; string Element; bool IsField;

可以安全地假设每个MyObject在myObjectElementCollection中具有相同数量的MyObjectElements,并且它们都具有匹配的Name和IsField属性。 仅当IsField属性设置为true时,我需要MyObject的myObjectElementCollection中每个MyObjectElement的列。 元素是每个单元格的值。

现在这是问题的第一部分:通过支持双向绑定来生成DataGrid。 这个问题的第二部分是DataGrid列类型。

我有2个类,MyObjectImage和MyObjectTextBox。 这些都从MyObjectElement继承。 MyObject中的集合myObjectElementCollection实际上并不包含任何MyObjectElements。 它只包含MyObjectImage和MyObjectTextBox对象。 如果MyObjectElement的类型是MyObjectTextBox,那么它应该只显示字符串。

但是,如果类型为MyObjectImage,则datagrid列应显示图像。 MyObjectImage包含一个属性,该属性是一个名为ImageType的字符串。 该字符串将始终为三个值中的一个:“PNG”,“XAML”或“SVG”。 如果它等于“PNG”,则假定Element是png的base64字符串是安全的。 如果它等于“XAML”,则可以安全地假定图像在元素中存储为大XAML字符串。 如果它等于“SVG”,那么可以安全地假设图像将是svg作为字符串,我有一个转换器函数,将其转换为XAML字符串。 用户可以通过双击单元格来更换图像,但这与问题无关。 假设ImageType属性将与其它myObjectElementCollections中的相关ImageTpe属性相匹配也是安全的。

如果您能够对此数据网格问题的任何部分输入任何建议,那将是非常棒的! 我几个星期以来一直在抨击我的头脑! 为了使事情变得更容易,这里是模型结构的一些示例代码(可以安全地假设INotifyPropertChanged在类ObservableObject中实现):

我的对象

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) { } }

再一次地,任何和所有的帮助表示赞赏与这个问题; 谢谢!

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!

最满意答案

我能够通过可以在这里找到的方法完成问题的第一部分。 这个问题的第二部分应该可以通过模板化传入的项来完成。我可以轻松创建一个图像属性,从任何一个转换为位图图像作为datagrid列的显示。

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.

更多推荐

MyObject,string,MyObjectElement,电脑培训,计算机培训,IT培训"/> <meta name=&qu

本文发布于:2023-07-05 07:04:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1034461.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:网格   绑定   动态   数据   mvvm

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!