XAML 绑定失败,将数据数组绑定到 DataGrid。

huangapple go评论70阅读模式
英文:

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: &#39;attributes&#39; property not found on &#39;myProject.Classes.User_Data.Objects.EquipmentData&#39;. 
BindingExpression: Path=&#39;data.attributes.status&#39; DataItem=&#39;myProject.Classes.User_Data.Objects.EquipmentData&#39;; target element is &#39;Windows.UI.Xaml.Controls.CheckBox&#39; (Name=&#39;null&#39;); target property is &#39;IsChecked&#39; (type &#39;Boolean&#39;)

<!-- end snippet -->

Here is my XAML:

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-html -->

&lt;controls:DataGrid
    x:Name=&quot;dataGrid&quot;
    x:FieldModifier=&quot;Public&quot;
    AutoGenerateColumns=&quot;False&quot;
    ItemsSource=&quot;{x:Bind Mode=OneWay, Path=dr_equipment.data}&quot;&gt;
    &lt;controls:DataGrid.Columns&gt;
        &lt;controls:DataGridCheckBoxColumn
            Width=&quot;40&quot;
            Binding=&quot;{Binding attributes.status}&quot;
            CanUserReorder=&quot;False&quot;
            CanUserResize=&quot;False&quot;
            CanUserSort=&quot;False&quot;
            Header=&quot;&quot;
            IsReadOnly=&quot;False&quot; /&gt;
    &lt;/controls:DataGrid.Columns&gt;
&lt;/controls:DataGrid&gt;

<!-- 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.

   &lt;Grid&gt;
&lt;controls:DataGrid
x:Name=&quot;dataGrid&quot;
x:FieldModifier=&quot;Public&quot;
AutoGenerateColumns=&quot;False&quot;
ItemsSource=&quot;{x:Bind Mode=OneWay, Path=dr_equipment.data}&quot;&gt;
&lt;controls:DataGrid.Columns&gt;
&lt;controls:DataGridTextColumn 
Header=&quot;id&quot; 
Width=&quot;SizeToCells&quot;
Binding=&quot;{Binding id}&quot; 
FontSize=&quot;20&quot; /&gt;
&lt;controls:DataGridCheckBoxColumn
Width=&quot;100&quot;
Binding=&quot;{Binding eq_attributes.status}&quot;        
Header=&quot;status&quot;/&gt;
&lt;/controls:DataGrid.Columns&gt;
&lt;/controls:DataGrid&gt;
&lt;/Grid&gt;

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 = &quot;001&quot;,type = &quot;safe&quot; , eq_attributes= attributes_0},
new EquipmentData{ id = &quot;002&quot;,type = &quot;happy&quot;, eq_attributes= attributes_1},
new EquipmentData{ id = &quot;003&quot;,type = &quot;safe&quot; , eq_attributes= attributes_0},
new EquipmentData{ id = &quot;004&quot;,type = &quot;happy&quot;, 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;
}
}

huangapple
  • 本文由 发表于 2023年5月18日 04:46:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76276082.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定