Pergunta

Em tempo de execução Eu quero colunas de grade dinamicamente construir (ou para outro layout de exibição) em um WPF ListView. Eu não sei o número e os nomes das colunas antes da mão.

Eu quero ser capaz de fazer:
MyListView.ItemSource = MyDataSet;
MyListView.CreateColumns ();

Foi útil?

Solução

Eu tentaria seguinte abordagem:

A) você precisa ter a caixa de exibição de lista grade de exibição - eu acredito isso você já fez
B) definir um estilo para GridViewColumnHeader:

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

No meu caso, eu tinha um monte de outras propriedades set, mas no cenário básico - você precisa de evento Loaded. Clicado - isto é útil se você quiser adicionar classificação e filtragem funcionalidade

.

C) em seu código listview, vincular o modelo com sua 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), em seguida, você OnHeaderLoaded manipulador, você pode definir um modelo adequado com base em dados da coluna

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

// selecionar e aplicar o seu modelo de dados aqui.

        e.Handled = true;
    }

E) Eu acho que você precisa também de propriedade aquisição de ItemsSource propriedade de dependência e lidar com isso mudou evento.

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

a classe GridViewColumn em si não tem muito propriedades, para que você pode querer adicionar algumas informações lá usando propriedades anexadas - ou seja, como tag coluna exclusiva - cabeçalho provavelmente serão utilizados para a localização, e você não vai retransmitir em um presente .

Em geral, esta abordagem, embora bastante complicado, vai permitir que você facilmente estender a funcionalidade de exibição de lista.

Outras dicas

Você pode adicionar colunas dinamicamente a um ListView usando propriedades anexadas. Confira este artigo sobre o CodeProject que explica exatamente o que ...

WPF DynamicListView - vinculação a um DataMatrix

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

Tenha um DataTemplateSelector para selecionar um dos modelos predefinidos (OF mesmo tipo de dados) e aplique o selector para o ListView. Você pode ter tantos DataTemplates com diferentes colunas.

Você pode usar um DataTemplateSelector para retornar um DataTemplate que você tenha criado dinamicamente no código. No entanto, este é um pouco entediante e mais complicado do que usar um pré-definida de XAML, mas ainda é possível. Ter um olhar para este exemplo: http: //dedjo.blogspot .com / 2007/03 / criando-DataTemplates-de-code.html

Por experiência, posso recomendar direção clara de modelos de dados dinâmica se você pode ajudá-lo ... sim usar o conselho dado aqui para explictly criar as colunas de ListView, ao invés de tentar criar um DataTemplate dinamicamente.

A razão é que o FrameworkElementFactory (ou qualquer que seja o nome da classe é para a produção de DataTemplates em tempo de execução) é um pouco cludgey ao uso (e é preterida em favor do uso de XAML para modelos dinâmicos.) - de qualquer forma você tomar uma batida desempenho

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top