英文:
XAML Binding Failure on binding an Array of data to a DataGrid
问题
我在一个C# UWP项目上工作,尝试将应用程序中的数据源("dr_equipment")绑定到DataGrid。这在之前是有效的,但在对JSON结构(dr_equipment的Equipment数据类型)进行一些更改后,现在在这个数据上出现绑定错误。
可视上,DataGrid显示了正确的列,但所有行都是空的。
我不确定确切地做了什么导致了这个问题,但我的错误表明在我的EquipmentData对象上找不到'attributes'属性。我已经检查了类,并且确实有一个'attributes'属性,它是公共的,但出于某种原因它无法识别。
额外的上下文:
- 我的XAML自上次工作以来并没有更改,只是数据结构发生了变化。
- 我没有单独的ViewModel。我在Page的代码后台中将数据存储在一个Equipment对象中(其中Equipment.data[i].attributes存储我绑定的不同属性)。
- 我可以确认dr_equipment.data[]已经填充(数组大小约为1800),每个.data.attributes都适当填充了数据。我会认为这不是与JSON序列化/反序列化有关的问题,而是与类本身有关的问题。
这里是绑定错误:
Error: BindingExpression path error: 'attributes' property not found on 'myProject.Classes.User_Data.Objects.EquipmentData'.
BindingExpression: Path='data.attributes.status' DataItem='myProject.Classes.User_Data.Objects.EquipmentData'; target element is 'Windows.UI.Xaml.Controls.CheckBox' (Name='null'); target property is 'IsChecked' (type 'Boolean')
这是我的XAML:
<controls:DataGrid
x:Name="dataGrid"
x:FieldModifier="Public"
AutoGenerateColumns="False"
ItemsSource="{x:Bind Mode=OneWay, Path=dr_equipment.data}">
<controls:DataGrid.Columns>
<controls:DataGridCheckBoxColumn
Width="40"
Binding="{Binding attributes.status}"
CanUserReorder="False"
CanUserResize="False"
CanUserSort="False"
Header=""
IsReadOnly="False" />
</controls:DataGrid.Columns>
</controls:DataGrid>
这是与"Equipment"(dr_equipment的类型)相关的类:
public class Equipment : DrupalObject
{
public new EquipmentData[] data { get; set; }
public Equipment()
{
}
}
public class EquipmentData : DrupalData
{
public EquipmentAttributes attributes { get; set; }
}
public class EquipmentAttributes : DrupalAttributes
{
public int drupal_internal__nid { get; set; }
public string title { get; set; }
public bool status { get; set; }
}
这是DrupalObject,Equipment扩展的类:
public class DrupalObject
{
public DrupalData[] data { get; set; }
public DrupalObject()
{
}
}
public class DrupalData
{
public string type { get; set; }
public string id { get; set; }
public DrupalAttributes attributes { get; set; }
}
public class DrupalAttributes
{
public int drupal_internal__tid { get; set; }
public bool status { get; set; }
public string name { get; set; }
public object description { get; set; }
public DateTime created { get; set; }
public DateTime changed { get; set; }
}
英文:
I am working on a C# UWP project and am attempting to bind a data source in my application ("dr_equipment") to a DataGrid. This was working before, but after making some changes to my JSON structure (the Equipment data type of dr_equipment), I am now getting binding errors on this data.
Visually, the DataGrid is displayed with the correct columns, but all rows are empty.
I am not sure exactly what I did that broke this, but my error is indicating that the 'attributes' property does not exist on my EquipmentData object. I reviewed the class and there is an 'attributes' property, which is public, but it is not recognizing that for some reason.
Additional context:
- My XAML has not changed since it was last working, just the data structures.
- I do not have a seperate ViewModel. I store the data in an Equipment object (with Equipment.data[i].attributes storing the different attributes I bind) in the Page code-behind.
- I can confirm that dr_equipment.data[] is filled (array size about 1800), and each .data.attributes is appropriately filled with data. I would assume this is not an issue with how the JSON is serialized/deserialized, but some issue with the class itself.
Here are the binding errors:
<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-html -->
Error: BindingExpression path error: 'attributes' property not found on 'myProject.Classes.User_Data.Objects.EquipmentData'.
BindingExpression: Path='data.attributes.status' DataItem='myProject.Classes.User_Data.Objects.EquipmentData'; target element is 'Windows.UI.Xaml.Controls.CheckBox' (Name='null'); target property is 'IsChecked' (type 'Boolean')
<!-- end snippet -->
Here is my XAML:
<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-html -->
<controls:DataGrid
x:Name="dataGrid"
x:FieldModifier="Public"
AutoGenerateColumns="False"
ItemsSource="{x:Bind Mode=OneWay, Path=dr_equipment.data}">
<controls:DataGrid.Columns>
<controls:DataGridCheckBoxColumn
Width="40"
Binding="{Binding attributes.status}"
CanUserReorder="False"
CanUserResize="False"
CanUserSort="False"
Header=""
IsReadOnly="False" />
</controls:DataGrid.Columns>
</controls:DataGrid>
<!-- end snippet -->
Here are the classes for and related to "Equipment" (type for dr_equipment):
<!-- begin snippet: js hide: true console: false babel: false -->
<!-- language: lang-html -->
// The purpose of extending DrupalObject is that DrupalObject contains generic data
// about the Drupal object that is relatively universal to these types of objects.
// Equipment adds additional attributes (which both serialize into
// Equipment.data.attributes)
public class Equipment : DrupalObject
{
public new EquipmentData[] data
{
get; set;
}
public Equipment()
{
}
}
public class EquipmentData : DrupalData
{
public EquipmentAttributes attributes
{
get; set;
}
}
public class EquipmentAttributes : DrupalAttributes
{
public int drupal_internal__nid
{
get; set;
}
public string title
{
get; set;
}
public bool status
{
get; set;
}
}
<!-- end snippet -->
And here are the classes for DrupalObject, which Equipment extends (Equipment : DrupalObject):
<!-- begin snippet: js hide: true console: false babel: false -->
<!-- language: lang-html -->
public class DrupalObject
{
public DrupalData[] data { get; set; }
public DrupalObject()
{
}
}
public class DrupalData
{
public string type { get; set; }
public string id { get; set; }
public DrupalAttributes attributes { get; set; }
}
public class DrupalAttributes
{
public int drupal_internal__tid
{
get; set;
}
public bool status
{
get; set;
}
public string name
{
get; set;
}
public object description
{
get; set;
}
public DateTime created
{
get; set;
}
public DateTime changed
{
get; set;
}
}
<!-- end snippet -->
答案1
得分: 1
You need to modify the naming of the members in your class EquipmentData
. EquipmentAttributes attributes
have the same name as DrupalAttributes attributes
in inherited DrupalData
.
以下是我的测试代码,希望能帮助您理解它。
<Grid>
<controls:DataGrid
x:Name="dataGrid"
x:FieldModifier="Public"
AutoGenerateColumns="False"
ItemsSource="{x:Bind Mode=OneWay, Path=dr_equipment.data}">
<controls:DataGrid.Columns>
<controls:DataGridTextColumn
Header="id"
Width="SizeToCells"
Binding="{Binding id}"
FontSize="20" />
<controls:DataGridCheckBoxColumn
Width="100"
Binding="{Binding eq_attributes.status}"
Header="status"/>
</controls:DataGrid.Columns>
</controls:DataGrid>
</Grid>
public sealed partial class MainPage : Page
{
Equipment dr_equipment = new Equipment();
public MainPage()
{
this.InitializeComponent();
EquipmentAttributes attributes_0 = new EquipmentAttributes {
status = true
};
EquipmentAttributes attributes_1 = new EquipmentAttributes
{
status = false
};
EquipmentData[] equipment = new EquipmentData[] {
new EquipmentData{ id = "001", type = "safe", eq_attributes = attributes_0},
new EquipmentData{ id = "002", type = "happy", eq_attributes = attributes_1},
new EquipmentData{ id = "003", type = "safe", eq_attributes = attributes_0},
new EquipmentData{ id = "004", type = "happy", eq_attributes = attributes_1}
};
dr_equipment.data = equipment;
}
}
public class Equipment : DrupalObject
{
public new EquipmentData[] data
{
get; set;
}
public Equipment()
{
}
}
public class EquipmentData : DrupalData
{
public EquipmentAttributes eq_attributes
{
get; set;
}
}
public class EquipmentAttributes : DrupalAttributes
{
public int drupal_internal__nid
{
get; set;
}
public string title
{
get; set;
}
public bool status
{
get; set;
}
}
public class DrupalObject
{
public DrupalData[] data { get; set; }
public DrupalObject()
{
}
}
public class DrupalData
{
public string type { get; set; }
public string id { get; set; }
public DrupalAttributes attributes { get; set; }
}
public class DrupalAttributes
{
public int drupal_internal__tid
{
get; set;
}
public bool status
{
get; set;
}
public string name
{
get; set;
}
public object description
{
get; set;
}
public DateTime created
{
get; set;
}
public DateTime changed
{
get; set;
}
}
英文:
You need to modify the naming of the members in your class EquipmentData
, EquipmentAttributes attributes
have the same name as DrupalAttributes attributes
in inherited DrupalData
.
The following is my test code, I hope it will help you understand it.
<Grid>
<controls:DataGrid
x:Name="dataGrid"
x:FieldModifier="Public"
AutoGenerateColumns="False"
ItemsSource="{x:Bind Mode=OneWay, Path=dr_equipment.data}">
<controls:DataGrid.Columns>
<controls:DataGridTextColumn
Header="id"
Width="SizeToCells"
Binding="{Binding id}"
FontSize="20" />
<controls:DataGridCheckBoxColumn
Width="100"
Binding="{Binding eq_attributes.status}"
Header="status"/>
</controls:DataGrid.Columns>
</controls:DataGrid>
</Grid>
public sealed partial class MainPage : Page
{
Equipment dr_equipment =new Equipment();
public MainPage()
{
this.InitializeComponent();
EquipmentAttributes attributes_0 = new EquipmentAttributes {
status=true
};
EquipmentAttributes attributes_1 = new EquipmentAttributes
{
status = false
};
EquipmentData[] equipment = new EquipmentData[] {
new EquipmentData{ id = "001",type = "safe" , eq_attributes= attributes_0},
new EquipmentData{ id = "002",type = "happy", eq_attributes= attributes_1},
new EquipmentData{ id = "003",type = "safe" , eq_attributes= attributes_0},
new EquipmentData{ id = "004",type = "happy", eq_attributes= attributes_1}
};
dr_equipment.data = equipment;
}
}
public class Equipment : DrupalObject
{
public new EquipmentData[] data
{
get; set;
}
public Equipment()
{
}
}
public class EquipmentData : DrupalData
{
public EquipmentAttributes eq_attributes
{
get; set;
}
}
public class EquipmentAttributes : DrupalAttributes
{
public int drupal_internal__nid
{
get; set;
}
public string title
{
get; set;
}
public bool status
{
get; set;
}
}
public class DrupalObject
{
public DrupalData[] data { get; set; }
public DrupalObject()
{
}
}
public class DrupalData
{
public string type { get; set; }
public string id { get; set; }
public DrupalAttributes attributes { get; set; }
}
public class DrupalAttributes
{
public int drupal_internal__tid
{
get; set;
}
public bool status
{
get; set;
}
public string name
{
get; set;
}
public object description
{
get; set;
}
public DateTime created
{
get; set;
}
public DateTime changed
{
get; set;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论