2008-09-24 100 views
4

在运行时,我想动态地在WPF ListView中构建网格列(或其他显示布局)。我不知道列表的数量和名称。在运行时动态创建WPF ItemTemplate

我希望能够做到:
MyListView.ItemSource = MyDataset;
MyListView.CreateColumns();

回答

1

我想尝试以下方法:

A)你需要有列表框中显示网格视图 - 我相信这一点,你已经
乙完成的)定义样式GridViewColumnHeader:

 <Style TargetType="{x:Type GridViewColumnHeader}" x:Key="gridViewColumnStyle"> 
      <EventSetter Event="Click" Handler="OnHeaderClicked"/> 
      <EventSetter Event="Loaded" Handler="OnHeaderLoaded"/> 
     </Style> 

在我的情况下,我有一大堆其他属性设置,但在基本情况下 - 你需要Loaded事件。点击 - 如果您想添加排序和筛选功能,这很有用。

C)在您的列表视图代码,绑定模板与你的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类本身没有太多的属性,所以你可能要在那里添加一些信息使用附加的属性 - 即像唯一列标签 - 标题很可能将用于本地化,你不会在这一个接力。

一般而言,这种方法即使相当复杂,也可以让您轻松扩展列表视图功能。

0

有一个DataTemplateselector选择一个预定义的模板(相同的DataType)并将选择器应用于ListView。您可以拥有具有不同列的多个DataTemplates。

+0

我不知道以前的列数或名称 - 这将如何帮助? – Peter 2008-09-24 07:38:10

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); 
0

从以往的经验,我可以推荐转向清晰的动态数据模板,如果你能帮助它... ...而使用这里给出的建议来显式创建的ListView列而不是试图动态地创建一个DataTemplate。

原因是FrameworkElementFactory(或者在运行时用于生成DataTemplates的任何类名)在使用(并且不赞成使用XAML用于动态模板)方面有点粗糙 - 无论哪种方式,都会使性能受到影响。