Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF使用嵌套属性将Datagrid绑定到ObservableCollection_C#_Wpf_Data Binding_Datagrid_Observablecollection - Fatal编程技术网

C# WPF使用嵌套属性将Datagrid绑定到ObservableCollection

C# WPF使用嵌套属性将Datagrid绑定到ObservableCollection,c#,wpf,data-binding,datagrid,observablecollection,C#,Wpf,Data Binding,Datagrid,Observablecollection,我想将DataGrid绑定到嵌套属性的集合。 我尝试了 但到目前为止运气不好 我得到的是一个空的DataGrid和控制台输出,如下所示: System.Windows.Data错误:2:找不到目标元素的治理FrameworkElement或FrameworkContentElement。BindingExpression:Path=AGNR.Key;DataItem=null;目标元素是“DataGridTextColumn”(HashCode=38805039);目标属性为“Header”(类

我想将DataGrid绑定到嵌套属性的集合。 我尝试了
但到目前为止运气不好

我得到的是一个空的DataGrid和控制台输出,如下所示:

System.Windows.Data错误:2:找不到目标元素的治理FrameworkElement或FrameworkContentElement。BindingExpression:Path=AGNR.Key;DataItem=null;目标元素是“DataGridTextColumn”(HashCode=38805039);目标属性为“Header”(类型为“Object”)

tcc_采集的输出也发生了变化(但不包括PropertyChangedHandler):

2016年12月30日11:11:22,收款变更

我使用现代UI(第一层)框架。以下是我的窗口代码:

public partial class Home : UserControl
{

    private ObservableTable<TableClass> tcc;

    public Home()
    {
        InitializeComponent();
    }

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        TableClass tc;
        List<TableClass> tcl = new List<TableClass>();

        tcc = new ObservableTable<TableClass>();

        tcc.CollectionChanged += tcc_CollectionChanged;
        tcc.ItemPropertyChanged += PropertyChangedHandler;

        for (int i = 0; i < 10; i++)
        {
            tc = new TableClass();

            tc.AGNR.Name = "AGNr";
            tc.AGNR.Value = i.ToString();

            tc.MNR.Name = "MNr";
            tc.MNR.Value = i.ToString() + " M";

            tc.MST.Name = "MSt";
            tc.MST.Value = i % 2 == 0 ? "production" : "stopped";

            tcc.Add(tc);
        }

    }

    static void PropertyChangedHandler(object sender, PropertyChangedEventArgs e)
    {
        Console.WriteLine(DateTime.Now.ToString() + ", Property changed");
        return;
    }

    static void tcc_CollectionChanged(object sender, EventArgs e)
    {
        Console.WriteLine(DateTime.Now.ToString() + ", Collection changed");
        return;
    }
}
KeyValueClass非常简单(我在这里需要什么?):


我需要在集合中嵌套这些属性,因为我可以用不同的语言获取这些数据。因此,我无法对网格的标题进行编码。

因为您只能绑定到公共属性,所以必须定义“tcc”。TableClass和KeyValueClass类型也必须是公共的:

public partial class Home : UserControl
{
    public ObservableCollection<TableClass> tcc { get; set; }

    public Home()
    {
        InitializeComponent();
        tcc = new ObservableCollection<TableClass>();
        DataContext = this;
    }

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        TableClass tc;
        List<TableClass> tcl = new List<TableClass>();

        tcc.CollectionChanged += tcc_CollectionChanged;

        for (int i = 0; i < 10; i++)
        {
            tc = new TableClass();

            tc.AGNR.Name = "AGNr";
            tc.AGNR.Value = i.ToString();

            tc.MNR.Name = "MNr";
            tc.MNR.Value = i.ToString() + " M";

            tc.MST.Name = "MSt";
            tc.MST.Value = i % 2 == 0 ? "production" : "stopped";

            tcc.Add(tc);
        }

    }

    static void PropertyChangedHandler(object sender, PropertyChangedEventArgs e)
    {
        Console.WriteLine(DateTime.Now.ToString() + ", Property changed");
        return;
    }

    static void tcc_CollectionChanged(object sender, EventArgs e)
    {
        Console.WriteLine(DateTime.Now.ToString() + ", Collection changed");
        return;
    }
}

public class TableClass : INotifyPropertyChanged
{
    private KeyValueClass _mnr;
    private KeyValueClass _agnr;
    private KeyValueClass _mst;

    public KeyValueClass MNR
    {
        get
        {
            return _mnr;
        }
        set
        {
            _mnr = value;
            NotifyPropertyChanged("MNR");
        }
    }
    public KeyValueClass AGNR
    {
        get
        {
            return _agnr;
        }
        set
        {
            _agnr = value;
            NotifyPropertyChanged("AGNR");
        }
    }
    public KeyValueClass MST
    {
        get
        {
            return _mst;
        }
        set
        {
            _mst = value;
            NotifyPropertyChanged("MST");
        }
    }

    public TableClass()
    {
        MNR = new KeyValueClass();
        AGNR = new KeyValueClass();
        MST = new KeyValueClass();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

public class KeyValueClass
{
    private string _name;
    private string _val;

    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
    public string Value
    {
        get
        {
            return _val;
        }
        set
        {
            _val = value;
        }
    }
}
public部分类主页:UserControl
{
公共可观测集合tcc{get;set;}
公共住宅()
{
初始化组件();
tcc=新的可观测集合();
DataContext=this;
}
已加载私有void UserControl_(对象发送方,RoutedEventArgs e)
{
表类tc;
List tcl=新列表();
tcc.CollectionChanged+=tcc\U CollectionChanged;
对于(int i=0;i<10;i++)
{
tc=新的TableClass();
tc.AGNR.Name=“AGNR”;
tc.AGNR.Value=i.ToString();
tc.MNR.Name=“MNR”;
tc.MNR.Value=i.ToString()+“M”;
tc.MST.Name=“MST”;
tc.MST.Value=i%2==0?“生产”:“已停止”;
tcc.Add(tc);
}
}
静态无效PropertyChangedHandler(对象发送方,PropertyChangedEventArgs e)
{
Console.WriteLine(DateTime.Now.ToString()+“,属性已更改”);
回来
}
静态无效tcc_集合已更改(对象发送方,事件参数e)
{
Console.WriteLine(DateTime.Now.ToString()+“,集合已更改”);
回来
}
}
公共类TableClass:INotifyPropertyChanged
{
private KeyValueClass\u mnr;
private KeyValueClass\u agnr;
private KeyValueClass_mst;
公钥值类MNR
{
收到
{
返回mnr;
}
设置
{
_mnr=数值;
通知财产变更(“MNR”);
}
}
公钥值类AGNR
{
收到
{
返回_agnr;
}
设置
{
_agnr=数值;
NotifyPropertyChanged(“AGNR”);
}
}
公钥值类MST
{
收到
{
返回mst;
}
设置
{
_mst=值;
NotifyPropertyChanged(“MST”);
}
}
公共表类()
{
MNR=新的KeyValueClass();
AGNR=新的KeyValueClass();
MST=新的KeyValueClass();
}
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged(字符串propertyName=“”)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
公共类KeyValueClass
{
私有字符串\u名称;
私有字符串_val;
公共字符串名
{
收到
{
返回_name;
}
设置
{
_名称=值;
}
}
公共字符串值
{
收到
{
返回值;
}
设置
{
_val=值;
}
}
}
没有内置的类ObservableTable,所以我在上面的示例代码中将这个类更改为ObservableCollection

您还应该将这些列添加到DataGrid的columns集合中:

<DataGrid x:Name="tcgrid" ItemsSource="{Binding tcc, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                  AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding AGNR.Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
                                Header="{Binding AGNR.Key, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
        <DataGridTextColumn Binding="{Binding MNR.Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
                                Header="{Binding MNR.Key, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
        <DataGridTextColumn Binding="{Binding MST.Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
                                Header="{Binding MST.Key, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
    </DataGrid.Columns>
</DataGrid>

然后它似乎起作用了:


您好mm8感谢您的回答和关于将“tcc”物业公之于众的建议。我以前将其设置为私有,因为它在没有公开我的类型的情况下给出了一个错误。我仍然会遇到同样的错误,无法为目标元素找到治理FrameworkElement或FrameworkContentElement,但是,正如您在图片中看到的,网格的标题是空的。结果对我来说仍然是一张空桌子。可观察表是从我在问题中引用的问题中“获取”的,看起来是这样的……不能在这里粘贴代码。如果KeyValueClass中的属性发生更改,我希望从该类获得通知。列标题的绑定应为AGNR.Name等。如果我尝试此操作,仍然为空标题每个列只有一个列标题,并且列标题没有DataContext,那么您希望在标题中显示哪个类的属性?一个列标题映射到多个TableClass对象,因此将标题绑定到TableClass对象的属性是没有意义的。。。
class KeyValueClass
{
    private string _name;
    private string _val;

    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
    public string Value
    {
        get
        {
            return _val;
        }
        set
        {
            _val = value;
        }
    }
}
public partial class Home : UserControl
{
    public ObservableCollection<TableClass> tcc { get; set; }

    public Home()
    {
        InitializeComponent();
        tcc = new ObservableCollection<TableClass>();
        DataContext = this;
    }

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        TableClass tc;
        List<TableClass> tcl = new List<TableClass>();

        tcc.CollectionChanged += tcc_CollectionChanged;

        for (int i = 0; i < 10; i++)
        {
            tc = new TableClass();

            tc.AGNR.Name = "AGNr";
            tc.AGNR.Value = i.ToString();

            tc.MNR.Name = "MNr";
            tc.MNR.Value = i.ToString() + " M";

            tc.MST.Name = "MSt";
            tc.MST.Value = i % 2 == 0 ? "production" : "stopped";

            tcc.Add(tc);
        }

    }

    static void PropertyChangedHandler(object sender, PropertyChangedEventArgs e)
    {
        Console.WriteLine(DateTime.Now.ToString() + ", Property changed");
        return;
    }

    static void tcc_CollectionChanged(object sender, EventArgs e)
    {
        Console.WriteLine(DateTime.Now.ToString() + ", Collection changed");
        return;
    }
}

public class TableClass : INotifyPropertyChanged
{
    private KeyValueClass _mnr;
    private KeyValueClass _agnr;
    private KeyValueClass _mst;

    public KeyValueClass MNR
    {
        get
        {
            return _mnr;
        }
        set
        {
            _mnr = value;
            NotifyPropertyChanged("MNR");
        }
    }
    public KeyValueClass AGNR
    {
        get
        {
            return _agnr;
        }
        set
        {
            _agnr = value;
            NotifyPropertyChanged("AGNR");
        }
    }
    public KeyValueClass MST
    {
        get
        {
            return _mst;
        }
        set
        {
            _mst = value;
            NotifyPropertyChanged("MST");
        }
    }

    public TableClass()
    {
        MNR = new KeyValueClass();
        AGNR = new KeyValueClass();
        MST = new KeyValueClass();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

public class KeyValueClass
{
    private string _name;
    private string _val;

    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            _name = value;
        }
    }
    public string Value
    {
        get
        {
            return _val;
        }
        set
        {
            _val = value;
        }
    }
}
<DataGrid x:Name="tcgrid" ItemsSource="{Binding tcc, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                  AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding AGNR.Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
                                Header="{Binding AGNR.Key, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
        <DataGridTextColumn Binding="{Binding MNR.Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
                                Header="{Binding MNR.Key, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
        <DataGridTextColumn Binding="{Binding MST.Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
                                Header="{Binding MST.Key, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
    </DataGrid.Columns>
</DataGrid>