在运行时,我想在WPF ListView中动态构建网格列(或其他显示布局)。我事先不知道列的数量和名称。
我希望能够做到:
MyListView.ItemSource = MyDataset;
MyListView.CreateColumns();
答案 0 :(得分:2)
您可以使用附加属性动态地将列添加到ListView。查看 CodeProject 上的这篇文章,它完全解释了......
答案 1 :(得分:2)
来自MSDN:
MyListBox.ItemsSource = view;
ListView myListView = new ListView();
GridView myGridView = new GridView();
myGridView.AllowsColumnReorder = true;
myGridView.ColumnHeaderToolTip = "Employee Information";
GridViewColumn gvc1 = new GridViewColumn();
gvc1.DisplayMemberBinding = new Binding("FirstName");
gvc1.Header = "FirstName";
gvc1.Width = 100;
myGridView.Columns.Add(gvc1);
GridViewColumn gvc2 = new GridViewColumn();
gvc2.DisplayMemberBinding = new Binding("LastName");
gvc2.Header = "Last Name";
gvc2.Width = 100;
myGridView.Columns.Add(gvc2);
GridViewColumn gvc3 = new GridViewColumn();
gvc3.DisplayMemberBinding = new Binding("EmployeeNumber");
gvc3.Header = "Employee No.";
gvc3.Width = 100;
myGridView.Columns.Add(gvc3);
//ItemsSource is ObservableCollection of EmployeeInfo objects
myListView.ItemsSource = new myEmployees();
myListView.View = myGridView;
myStackPanel.Children.Add(myListView);
答案 2 :(得分:1)
我会尝试以下方法:
A)你需要让列表框显示网格视图 - 我相信你已经完成了 B)为GridViewColumnHeader定义样式:
<Style TargetType="{x:Type GridViewColumnHeader}" x:Key="gridViewColumnStyle">
<EventSetter Event="Click" Handler="OnHeaderClicked"/>
<EventSetter Event="Loaded" Handler="OnHeaderLoaded"/>
</Style>
在我的情况下,我有一大堆其他属性设置,但在基本场景中 - 你需要Loaded事件。单击 - 如果要添加排序和过滤功能,这将非常有用。
C)在listview代码中,将模板与gridview绑定:
public MyListView()
{
InitializeComponent();
GridView gridViewHeader = this.listView.View as GridView;
System.Diagnostics.Debug.Assert(gridViewHeader != null, "Expected ListView.View should be GridView");
if (null != gridViewHeader)
{
gridViewHeader.ColumnHeaderContainerStyle = (Style)this.FindResource("gridViewColumnStyle");
}
}
D)然后在你的OnHeaderLoaded处理程序中,你可以根据列的数据设置一个合适的模板
void OnHeaderLoaded(object sender, RoutedEventArgs e)
{
GridViewColumnHeader header = (GridViewColumnHeader)sender;
GridViewColumn column = header.Column;
//在此处选择并应用您的数据模板。
e.Handled = true;
}
E)我猜您还需要获取ItemsSource依赖项属性的所有权并处理它已更改的事件。
ListView.ItemsSourceProperty.AddOwner(typeof(MyListView), new PropertyMetadata(OnItemsSourceChanged));
static void OnItemsSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
MyListView view = (MyListView)sender;
//do reflection to get column names and types
//and for each column, add it to your grid view:
GridViewColumn column = new GridViewColumn();
//set column properties here...
view.Columns.Add(column);
}
GridViewColumn类本身没有太多属性,因此您可能希望使用附加属性在那里添加一些信息 - 例如像唯一列标记一样 - 标题最有可能用于本地化,并且您不会在此中继。
通常,这种方法即使非常复杂,也可以让您轻松扩展列表视图功能。
答案 3 :(得分:0)
使用 DataTemplateselector 选择一个预定义模板(相同的DataType)并将选择器应用于ListView。您可以使用不同列的DataTemplates。
答案 4 :(得分:0)
您可以使用 DataTemplateSelector 返回您在代码中动态创建的DataTemplate。但是,这比使用XAML中预定义的一个有点繁琐和复杂,但它仍然是可能的。 看一下这个例子:http://dedjo.blogspot.com/2007/03/creating-datatemplates-from-code.html
答案 5 :(得分:0)
根据经验,如果您可以提供帮助,我建议您不要使用动态数据模板...而是使用此处给出的建议明确创建ListView列,而不是尝试动态创建DataTemplate。
原因是FrameworkElementFactory(或任何类名用于在运行时生成DataTemplates)使用起来有些笨拙(并且不赞成将XAML用于动态模板) - 无论哪种方式都会影响性能。 / p>