Pregunta

En tiempo de ejecución, quiero crear dinámicamente columnas de cuadrícula (u otro diseño de visualización) en un ListView de WPF.No sé el número ni los nombres de las columnas de antemano.

Quiero poder hacer:
MyListView.ItemSource = Mi conjunto de datos;
MyListView.CreateColumns();

¿Fue útil?

Solución

Intentaría seguir el enfoque:

A) necesita tener la vista de cuadrícula del cuadro de lista; creo que esto ya lo ha hecho
B) definir un estilo para GridViewColumnHeader:

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

en mi caso, tenía muchas otras propiedades configuradas, pero en el escenario básico, necesitarías el evento Loaded.Se hizo clic: esto es útil si desea agregar funciones de clasificación y filtrado.

C) en su código de vista de lista, vincule la plantilla con su vista de cuadrícula:

    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) luego, en su controlador OnHeaderLoaded, puede configurar una plantilla adecuada basada en los datos de la columna

    void OnHeaderLoaded(object sender, RoutedEventArgs e)
    {
        GridViewColumnHeader header = (GridViewColumnHeader)sender;
        GridViewColumn column = header.Column;

//selecciona y aplica tu plantilla de datos aquí.

        e.Handled = true;
    }

E) Supongo que también necesitarías adquirir la propiedad de la propiedad de dependencia ItemsSource y manejar su evento modificado.

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

la clase GridViewColumn en sí no tiene muchas propiedades, por lo que es posible que desee agregar información allí utilizando las propiedades adjuntas, es decir,como etiqueta de columna única: el encabezado probablemente se usará para la localización y no transmitirá este.

En general, este enfoque, aunque bastante complicado, le permitirá ampliar fácilmente la funcionalidad de vista de lista.

Otros consejos

Puede agregar columnas dinámicamente a un ListView mediante Propiedades adjuntas.Consulte este artículo sobre el Proyecto de código explica exactamente eso...

WPF DynamicListView: enlace a DataMatrix

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

Tener un selector de plantillas de datos para seleccionar una de las plantillas predefinidas (del mismo tipo de datos) y aplicar el selector a ListView.Puede tener tantas plantillas de datos con diferentes columnas.

Puedes usar un Selector de plantilla de datos para devolver un DataTemplate que ha creado dinámicamente en código.Sin embargo, esto es un poco tedioso y más complicado que usar uno predefinido de XAML, pero aún es posible.Eche un vistazo a este ejemplo: http://dedjo.blogspot.com/2007/03/creating-datatemplates-from-code.html

Por experiencia, puedo recomendar que te mantengas alejado de las plantillas de datos dinámicos si puedes evitarlo...en lugar de ello, utilice los consejos que se dan aquí para crear explícitamente las columnas ListView, en lugar de intentar crear un DataTemplate dinámicamente.

La razón es que FrameworkElementFactory (o cualquiera que sea el nombre de la clase para producir DataTemplates en tiempo de ejecución) es algo complicado de usar (y está en desuso a favor del uso de XAML para plantillas dinámicas); de cualquier manera, el rendimiento se ve afectado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top