我想将DataGrid绑定到嵌套属性的集合。 我尝试了解决方案 WPF: Bound datagrid does not update items properties 但到目前为止没有运气。
我得到的是一个空的DataGrid和Console输出:
System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径= AGNR.Key;的DataItem = NULL;目标元素是' DataGridTextColumn' (的HashCode = 38805039);目标属性是'标题' (键入'对象')
也是从tcc_CollectionChanged(但不是PropertyChangedHandler)输出:
30.12.2016 11:11:22,收藏已更改
我使用Modern UI(firstfloor)框架。这是我的Window代码:
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;
}
}
对应的XAML:
<UserControl x:Class="MuiWpfTestApp.Pages.Home"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Loaded="UserControl_Loaded">
<Grid Style="{StaticResource ContentRoot}">
<ScrollViewer>
<DataGrid x:Name="tcgrid" ItemsSource="{Binding tcc, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="250" Width="250">
<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>
</ScrollViewer>
</Grid>
INotifyPropertyChanged在TableClass中实现:
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));
}
}
}
KeyValueClass非常简单(我在这里需要什么?):
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;
}
}
}
我在Collection中需要这个嵌套的属性,因为我可以用不同的语言获取这些数据。所以我无法对网格的标题进行编码。
答案 0 :(得分:0)
由于您只能绑定到公共属性,因此您必须定义&#34; tcc&#34;因此。您的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;
}
}
}
没有内置的ObservableTable类,所以我在上面的示例代码中将此更改为ObservableCollection。
您还应该将列添加到DataGrid的列集合中:
<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>
然后似乎有效: