wpf DataGrid пользовательских элементов управления

Я пытаюсь иметь DataGrid, который показывает пользовательские элементы управления в каждой ячейке его строк. подчеркивая, что DataGrid должен быть динамическим, поскольку количество столбцов является динамическим для каждого случая использования.

В моем коде xaml (XAML) это как объявление DataGrid:

<Grid Grid.Column="1" Margin="0,10,0,0">
      <DataGrid AutoGenerateColumns="False" x:Name="planningTable" FrozenColumnCount="1"/> 
</Grid>

Мой пользовательский элемент управления выглядит так (UserControl уже создан и работает отлично): введите описание изображения здесь

В результате DataGrid я хочу иметь этот UserControl в каждой ячейке DataGrid, это означает, что строки DataGrid должны отображать этот UserControl в каждой ячейке. Я много искал этот трюк, но кажется, что DataGrid не может разместить UserControl в ячейках.

Я хочу иметь код C #, который делает это, пожалуйста, не используйте код XAML, потому что он весь динамический !!


person AouledIssa    schedule 31.05.2014    source источник
comment
Вы можете получить это в XAML-формате (это будет слишком аккуратно и динамично). Но вам нужно добавить больше деталей, сколько столбцов и строк вы хотите? ItemsSource привязан к какой-либо коллекции?   -  person Rohit Vats    schedule 31.05.2014
comment
Да, это правда, что это можно сделать динамически с XAML через DataBinding. но я хочу иметь код C #, который делает это, потому что я не использую привязку данных!   -  person AouledIssa    schedule 31.05.2014


Ответы (1)


Как я уже упоминал в комментарии, вы можете делать это динамически только с помощью XAML. Выполняя это в коде позади, вы можете написать много кода и потерять важные функции WPF. Наиболее важно UI Virtualization, если вы сами создаете строки вручную.


Если вам не нужна поддержка привязки и вы хотите показать простой dataGrid со всеми ячейками, заполненными вашим UserControl, вы можете сделать это следующим образом:

Он покажет 2 столбца и 100 строк, заполненных вашим пользовательским элементом управления:

<Grid>
    <Grid.Resources>
        <ObjectDataProvider x:Key="EnumerableRange"
                 xmlns:sys="clr-namespace:System;assembly=mscorlib"
                 xmlns:linq="clr-namespace:System.Linq;assembly=System.Core"
                 ObjectType="{x:Type linq:Enumerable}" MethodName="Range">
            <ObjectDataProvider.MethodParameters>
                <sys:Int32>1</sys:Int32>
                <sys:Int32>100</sys:Int32>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Grid.Resources>
    <DataGrid AutoGenerateColumns="False" IsReadOnly="True"
            CanUserAddRows="False"
            CanUserDeleteRows="False"
            ItemsSource="{Binding Source={StaticResource EnumerableRange}}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Test1">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <local:SampleUserControl/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Test2">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <local:SampleUserControl/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

ОБНОВЛЕНИЕ

Если вы хотите динамически устанавливать столбцы, как я уже упоминал в своих комментариях, вам нужно установить AutoGenerateColumns на False и вручную добавить коллекцию столбцов. Вместо того, чтобы создавать DataGridTemplateColumns вручную, вы можете объявить его в разделе ресурсов DataGrid и использовать в коде.

XAML:

<Grid>
    <Grid.Resources>
        <ObjectDataProvider x:Key="EnumerableRange"
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            xmlns:linq="clr-namespace:System.Linq;assembly=System.Core"
            ObjectType="{x:Type linq:Enumerable}" MethodName="Range">
            <ObjectDataProvider.MethodParameters>
                <sys:Int32>1</sys:Int32>
                <sys:Int32>100</sys:Int32>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Grid.Resources>
    <DataGrid AutoGenerateColumns="False"
                x:Name="dataGrid"
                IsReadOnly="True"
                CanUserAddRows="False"
                CanUserDeleteRows="False"
                ItemsSource="{Binding Source={StaticResource EnumerableRange}}">
        <DataGrid.Resources>
            <DataGridTemplateColumn x:Key="TemplateColumn" x:Shared="False">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <local:SampleUserControl/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Resources>
    </DataGrid>
</Grid>

Код позади

public partial class MainWindow : Window
{
    private void CreateDataGridColumns()
    {
        for (int i = 0; i < 10; i++) // Change number of columns here.
        {
            DataGridTemplateColumn templateColumn = 
                  (DataGridTemplateColumn)dataGrid.Resources["TemplateColumn"];
            templateColumn.Header = String.Format("Test {0}", i + 1);
            dataGrid.Columns.Add(templateColumn);
        }
    }

    public MainWindow()
    {
        InitializeComponent();
        CreateDataGridColumns();
    }
}
person Rohit Vats    schedule 31.05.2014
comment
Большое спасибо @Rohit, он отлично работает !!! Я такой замечательный. Не могли бы вы рассказать мне, как сделать подсчет столбцов динамическим, например, иногда это 6 столбцов и X столбцов в другой раз - person AouledIssa; 31.05.2014
comment
подскажите, пожалуйста, как сделать счетчик столбцов DataGrid динамическим ?? Я буду очень рад этому. - person AouledIssa; 31.05.2014
comment
Чтобы сделать столбцы динамическими, вы должны установить AutoGenerateColumns=True в dataGrid и связать ItemsSource с объектом привязки. Он будет генерировать столбцы, равные количеству свойств в базовом объекте. - person Rohit Vats; 31.05.2014
comment
Вы также можете обратиться к этому, если не заинтересованы в создании базового объекта для ItemsSource - stackoverflow.com/questions/1983033/. - person Rohit Vats; 31.05.2014
comment
Кажется, я не могу этого сделать, потому что ItemsSource привязан к строкам: EnumerableRange, есть ли у вас другое решение? - person AouledIssa; 31.05.2014
comment
Другой способ - вручную добавить столбцы из кода при загрузке dataGrid. Но, как я уже сказал, если вы это сделаете, вы потеряете виртуализацию пользовательского интерфейса, т.е. если вы добавите, например, 10 столбцов, вы увидите некоторое отставание от их отображения в пользовательском интерфейсе. Но если вы вручную добавите 10 столбцов в XAML, это отобразится мгновенно. - person Rohit Vats; 31.05.2014
comment
Итак, если я понимаю, мне нужно выполнить несколько привязок, где одна предназначена для столбцов, а вторая - для строк? - person AouledIssa; 31.05.2014
comment
Я обновился с другим подходом в ответ. Посмотрите, работает ли это для вас. (Очевидно, что привязка - лучший способ, но это тоже сработает, если вы не хотите ничего связывать). - person Rohit Vats; 31.05.2014
comment
Большое спасибо, брат !!! Вы брелиант !!!! Ооочень большое спасибо !! - person AouledIssa; 31.05.2014
comment
Вы хоть представляете, как разместить текст в заголовке каждой строки? Я имею в виду, что у меня есть список строк, содержащий имена, и его нужно поместить в заголовок каждой строки. - person AouledIssa; 31.05.2014