WPF 如何使用 GridViewColumns(ListView 绑定)添加绑定到数组元素的列
WPF How to add columns bound to array elements using GridViewColumns (ListView Binding)
我正在制作一个数据可视化应用程序,我已经在 XAML 中编写了 3 列并成功绑定,但我正在尝试让用户能够在运行时添加列。
我正在尝试将列 header 绑定到在文本框中输入的值,该值进入 class 实现 INotifyPropertyChanged,并将单元格的值绑定到列表中的元素出现在 DataContext 的 objects 列表中。
如果这有用,我正在使用 .NET 4.7.2
有问题的class:
public class ColumnDescriptor : INotifyPropertyChanged
{
private string nom;
public event PropertyChangedEventHandler PropertyChanged;
public string Nom
{
get
{
return nom;
}
set
{
nom = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Nom)));
}
}
我尝试使用转换器的(不成功的)绑定,但它没有被调用
private void NewColumnEvent_Handler(ColumnDescriptor columnDescriptor, int columnIndex)
{
Binding b = new Binding("Columns[0]")
{
Converter = new NumberToColumnConverter(),
ConverterParameter = columnIndex.ToString(),
Mode = BindingMode.OneWay
};
GridViewColumn gridViewColumn = new GridViewColumn
{
Header = "Name",
DisplayMemberBinding = b
};
mainWindow.lvGridView.Columns.Add(gridViewColumn);
UpdateListViewDataContext();
}
listView.View
的XAML代码
<ListView.View>
<GridView x:Name="lvGridView">
<GridViewColumn Header="Id" Width="125">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Id}" Foreground="{Binding MessageColor}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Titre" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Titre}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="XPath_Resultat" Width="262">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath_Resultat}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
这是 DataContext 中使用的 class 的摘录,其中包含我想在绑定过程中使用的列表
class DataToBind
{
public List<string> Columns{get;set;}
}
向列表视图添加行时出现此错误
System.Windows.Data Error: 40 : BindingExpression path error: 'Columns' property not found on 'object' ''DataToBind' (HashCode=5641212)'. BindingExpression:Path=Columns[0]; DataItem='DataToBind' (HashCode=5641212); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
如有任何帮助,我们将不胜感激
编辑:通过将变量更改为 属性 ->
来修复绑定
public List<string> Columns{get;set;}
不过我仍在寻找 Header 绑定
您可以通过多种方式为您的行视图模型 (rowvm) 执行此类操作。
如果您不需要来自视图模型的更改通知,那么您可以使用 expandoobject。这允许您动态添加属性。
https://docs.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?view=netframework-4.8
您也可以使用依赖对象作为 rowvm。
然后您可以动态添加附加的依赖属性。
这些将通知更改。
如果你特别想要一个普通的 class 作为 rowvm 那么你可以使用 dr wpf 的 observabledictionary:
http://drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/
然后您可以通过向您的 observabledictionary 添加一个键值对来为每个添加一列。
使用名称绑定。
您当然需要迭代整个 rowvm 集合以添加给定列的键值对。
另一种选择是使用 ICustomTypeProvider 动态构建 rowvm。
https://www.c-sharpcorner.com/article/wpf-data-binding-with-icustomtypeprovider/
我正在制作一个数据可视化应用程序,我已经在 XAML 中编写了 3 列并成功绑定,但我正在尝试让用户能够在运行时添加列。
我正在尝试将列 header 绑定到在文本框中输入的值,该值进入 class 实现 INotifyPropertyChanged,并将单元格的值绑定到列表中的元素出现在 DataContext 的 objects 列表中。
如果这有用,我正在使用 .NET 4.7.2
有问题的class:
public class ColumnDescriptor : INotifyPropertyChanged
{
private string nom;
public event PropertyChangedEventHandler PropertyChanged;
public string Nom
{
get
{
return nom;
}
set
{
nom = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Nom)));
}
}
我尝试使用转换器的(不成功的)绑定,但它没有被调用
private void NewColumnEvent_Handler(ColumnDescriptor columnDescriptor, int columnIndex)
{
Binding b = new Binding("Columns[0]")
{
Converter = new NumberToColumnConverter(),
ConverterParameter = columnIndex.ToString(),
Mode = BindingMode.OneWay
};
GridViewColumn gridViewColumn = new GridViewColumn
{
Header = "Name",
DisplayMemberBinding = b
};
mainWindow.lvGridView.Columns.Add(gridViewColumn);
UpdateListViewDataContext();
}
listView.View
的XAML代码<ListView.View>
<GridView x:Name="lvGridView">
<GridViewColumn Header="Id" Width="125">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Id}" Foreground="{Binding MessageColor}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Titre" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Titre}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="XPath_Resultat" Width="262">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath_Resultat}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
这是 DataContext 中使用的 class 的摘录,其中包含我想在绑定过程中使用的列表
class DataToBind
{
public List<string> Columns{get;set;}
}
向列表视图添加行时出现此错误
System.Windows.Data Error: 40 : BindingExpression path error: 'Columns' property not found on 'object' ''DataToBind' (HashCode=5641212)'. BindingExpression:Path=Columns[0]; DataItem='DataToBind' (HashCode=5641212); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
如有任何帮助,我们将不胜感激
编辑:通过将变量更改为 属性 ->
来修复绑定public List<string> Columns{get;set;}
不过我仍在寻找 Header 绑定
您可以通过多种方式为您的行视图模型 (rowvm) 执行此类操作。
如果您不需要来自视图模型的更改通知,那么您可以使用 expandoobject。这允许您动态添加属性。
https://docs.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?view=netframework-4.8
您也可以使用依赖对象作为 rowvm。
然后您可以动态添加附加的依赖属性。
这些将通知更改。
如果你特别想要一个普通的 class 作为 rowvm 那么你可以使用 dr wpf 的 observabledictionary:
http://drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/
然后您可以通过向您的 observabledictionary 添加一个键值对来为每个添加一列。
使用名称绑定。
您当然需要迭代整个 rowvm 集合以添加给定列的键值对。
另一种选择是使用 ICustomTypeProvider 动态构建 rowvm。 https://www.c-sharpcorner.com/article/wpf-data-binding-with-icustomtypeprovider/