代码之家  ›  专栏  ›  技术社区  ›  Peter

在运行时动态创建WPF项模板

  •  4
  • Peter  · 技术社区  · 16 年前

    在运行时,我希望在WPF ListView中动态构建网格列(或其他显示布局)。我不知道前面的列的编号和名称。

    我想能够做到:
    myListView.itemsource=myDataSet;
    myListView.createColumns();

    6 回复  |  直到 16 年前
        1
  •  1
  •   Greg    16 年前

    我会尝试以下方法:

    a)您需要让列表框显示网格视图-我相信您已经这样做了。
    b)定义GridViewColumnHeader的样式:

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

    在我的例子中,我设置了许多其他属性,但是在基本场景中——您需要加载事件。单击-如果要添加排序和筛选功能,这很有用。

    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依赖属性的所有权,并处理它的changed事件。

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

    一般来说,这种方法,即使非常复杂,也允许您轻松地扩展列表视图功能。

        2
  •  2
  •   Tawani    16 年前

    可以使用附加的属性将列动态添加到ListView。看看这篇文章 代码项目 这正好解释了…

    WPF DynamicListView - Binding to a DataMatrix

        3
  •  2
  •   treehouse    16 年前

    来自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);
    
        4
  •  0
  •   Jobi Joy    16 年前

    有一个 数据模板选择器 选择一个预定义的模板(数据类型相同)并将选择器应用于ListView。您可以拥有任意多个具有不同列的数据模板。

        5
  •  0
  •   EFrank    16 年前

    你可以使用 数据模板选择器 返回在代码中动态创建的数据模板。但是,这比使用来自XAML的预定义的有点繁琐和复杂,但是仍然是可能的。 看看这个例子: http://dedjo.blogspot.com/2007/03/creating-datatemplates-from-code.html

        6
  •  0
  •   Mark    16 年前

    根据经验,如果你能帮助的话,我可以建议你避开动态数据模板…而是使用这里给出的建议明确地创建listview列,而不是尝试动态地创建数据模板。

    原因是frameworkElementFactory(或任何类名用于在运行时生成数据模板)使用起来有点笨拙(不赞成使用xaml来创建动态模板),无论哪种方式都会影响性能。