Создать WPF ItemTemplate DYNAMICALLY во время выполнения - PullRequest
4 голосов
/ 24 сентября 2008

Во время выполнения я хочу динамически создавать столбцы сетки (или другую схему отображения) в WPF ListView. Я не знаю количество и названия столбцов перед рукой.

Я хочу иметь возможность сделать:
MyListView.ItemSource = MyDataset;
MyListView.CreateColumns ();

Ответы [ 6 ]

2 голосов
/ 16 мая 2009

Из 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);
2 голосов
/ 15 мая 2009

Вы можете динамически добавлять столбцы в ListView, используя Attached Properties. Прочтите эту статью о CodeProject , это объясняет, что именно ...

WPF DynamicListView - привязка к DataMatrix

1 голос
/ 24 сентября 2008

я бы попробовал следующий подход:

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 голосов
/ 24 мая 2009

Исходя из своего опыта, я могу порекомендовать избежать динамических шаблонов данных, если вы можете в этом помочь ... вместо этого используйте приведенный здесь совет для явного создания столбцов ListView, а не пытайтесь динамически создавать DataTemplate.

Причина в том, что FrameworkElementFactory (или какое-либо другое имя класса для создания DataTemplates во время выполнения) несколько неудобно для использования (и не рекомендуется в пользу использования XAML для динамических шаблонов) - в любом случае вы получаете снижение производительности.

0 голосов
/ 16 октября 2008

Вы можете использовать DataTemplateSelector , чтобы возвратить DataTemplate, который вы динамически создали в коде. Однако это немного утомительно и сложнее, чем использование предопределенного из XAML, но это все же возможно. Посмотрите на этот пример: http://dedjo.blogspot.com/2007/03/creating-datatemplates-from-code.html

0 голосов
/ 24 сентября 2008

Имейте DataTemplateselector , чтобы выбрать один из предопределенных шаблонов (с тем же типом данных) и применить селектор к ListView. Вы можете иметь как можно больше шаблонов данных с разными столбцами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...