4

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

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

4

6 回答 6

3

您可以使用附加属性将列动态添加到 ListView。查看CodeProject上的这篇文章,它准确地解释了......

WPF DynamicListView - 绑定到 DataMatrix

于 2009-05-15T06:05:10.683 回答
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);
于 2009-05-16T12:15:03.500 回答
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)在您的列表视图代码中,将模板与您的网格视图绑定:

    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 类本身没有太多属性,因此您可能希望使用附加属性在其中添加一些信息 - 即像唯一的列标记 - 标题很可能会用于本地化,并且您不会中继这个。

一般来说,这种方法虽然相当复杂,但可以让您轻松扩展列表视图功能。

于 2008-09-24T16:08:22.863 回答
0

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

于 2008-09-24T06:47:20.607 回答
0

您可以使用DataTemplateSelector返回您在代码中动态创建的 DataTemplate。但是,这比使用 XAML 中的预定义有点繁琐且复杂,但仍然可以。看看这个例子:http ://dedjo.blogspot.com/2007/03/creating-datatemplates-from-code.html

于 2008-10-16T15:18:57.440 回答
0

根据经验,如果您能提供帮助,我建议您不要使用动态数据模板……而是使用此处给出的建议来明确创建 ListView 列,而不是尝试动态创建 DataTemplate。

原因是 FrameworkElementFactory(或用于在运行时生成 DataTemplates 的任何类名)使用起来有些笨拙(并且不推荐使用 XAML 来支持动态模板)——无论哪种方式都会对性能造成影响。

于 2009-05-23T20:20:51.767 回答