WPF DataGrid: привязка DataGridComboxBox ItemsSource к набору наборов

Ленивая инициализация параметра! Помимо всех предыдущих ответов (стратегическая модель, шаблон "наблюдатель", и т.д.), делегаты позволяют Вам обрабатывать ленивую инициализацию параметров. Например, предположите, что у Вас есть функциональная Загрузка (), который занимает довольно много времени и возвращает определенный DownloadedObject. Этот объект используется устройством хранения данных в зависимости от определенные условия. Как правило, Вы были бы:

storage.Store(conditions, Download(item))

Однако с делегатами (более точно, лямбды) можно сделать следующее путем изменения подписи хранилища так, чтобы это получило Условие и Func< Объект, DownloadedObject> и используйте его как это:

storage.Store(conditions, (item) => Download(item))

Поэтому устройство хранения данных только оценит делегата при необходимости, выполняя загрузку в зависимости от Условий.

11
задан 11 revs, 3 users 95% 28 September 2012 в 21:40
поделиться

5 ответов

Во-первых, это должно быть легко... во-вторых, почему вы строите (и связываете) столбцы в C#? Ик.

XAML (я использую обычный грид, потому что мне лень):

<ListView Name="MyListView">
    <ListView.View>
        <GridView>

            <GridView.Columns>

                <GridViewColumn DisplayMemberBinding="{Binding Operation}" />

                <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Choices}" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>

            </GridView.Columns>

        </GridView>
    </ListView.View>
</ListView>

C#:

void Window1_Loaded(object sender, RoutedEventArgs e)
{
    var dahList = new List<StatsOperation>();

    dahList.Add(new StatsOperation
    {
        Operation = "Op A",
        Choices = new string[] { "One", "Two", "Three" },
    });

    dahList.Add(new StatsOperation
    {
        Operation = "Op B",
        Choices = new string[] { "4", "5", "6" },
    });

    this.MyListView.ItemsSource = dahList;
}

Результаты:

WPF грид с динамическим выбором в комбобоксе http://www.singingeels.com/Articles/Articles/UserImage.aspx?ImageID=b1e3f880-c278-4d2b-bcc2-8ad390591200

11
ответ дан 3 December 2019 в 06:46
поделиться

Я думаю, ошибка в том, как вы сделали привязку. Когда вы определяете столбец, привязка связана с объектом, который представлен определенной строкой. Насколько я понимаю, у вас есть StatsOperation для каждой строки, поэтому столбец TextBox привязан к операции, как и у вас, а столбец ItemsSource ComboBox должен быть привязан к коллекции. Сейчас похоже, что он привязан к Collection > .

Раньше я не определял столбцы в коде программной части, поэтому вот пример в XAML. Я обнаружил, что ComboBoxColumn иногда может быть сложной задачей, поэтому я показал, как можно создать поле со списком в столбце, используя TemplateColumn или ComboBoxColumn. Я скопировал вставку из своего собственного кода, поэтому в вашем случае просто замените dg на WPFToolkit:

<dg:DataGrid
      ...
      ...>
      <dg:DataGrid.Columns>
            <dg:DataGridTextColumn Binding="{Binding Operation}" CanUserReorder="True" CanUserResize="True" Header="Operation" />
            <dg:DataGridTemplateColumn CanUserReorder="True" CanUserResize="True" Header="Template Column">
                <dg:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Data}" SelectedItem="{Binding Operation}" />
                    </DataTemplate>
                </dg:DataGridTemplateColumn.CellTemplate>
            </dg:DataGridTemplateColumn>
            <dg:DataGridComboBoxColumn
                Header="ComboBox Column"                                                                                    
                 SelectedValueBinding="{Binding Operation}"                     
                 SelectedItemBinding="{Binding Operation}">
                <dg:DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
                        <Setter Property="ItemsSource" Value="{Binding Data}" />
                    </Style>
                </dg:DataGridComboBoxColumn.ElementStyle>
                <dg:DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding Data}" />
                        <Setter Property="IsDropDownOpen" Value="True" />
                    </Style>
                </dg:DataGridComboBoxColumn.EditingElementStyle>
            </dg:DataGridComboBoxColumn>
      </dg:DataGrid.Columns>

</dg:DataGrid>

Я предполагаю, что Operation - это выбранный элемент, Data - это элементы, из которых нужно выбрать, и что ваш DataGrid привязан к коллекции StatsOperation. Удачи!

4
ответ дан 3 December 2019 в 06:46
поделиться

РЕДАКТИРОВАТЬ Извините, я немного медлителен в полночь :). Вот обновленный ответ. Похоже, отличная статья Винсента Сибала WPF DataGrid - DataGridComboBoxColumn v1 Intro отвечает на ваш вопрос. Это так?

1
ответ дан 3 December 2019 в 06:46
поделиться

Для исправления ошибки ItemsSource Binding Error используйте форму:

BindingOperations.SetBinding(new DataGridComboBoxColumn(), DataGridComboBoxColumn.ItemsSourceProperty, new Binding("Data"));

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

2
ответ дан 3 December 2019 в 06:46
поделиться

Частично - я думаю, что в ваших словах есть путаница. Вы сказали, что вам нужна коллекция строк в каждой строке, чтобы комбобокс мог показывать разные строки для разных строк. Однако для того, чтобы в комбобоксе отображался набор строк, вам нужна только коллекция строк в каждой строке, а не коллекция коллекций строк.

Теперь, поскольку вам нужна коллекция строк на строку, вы можете подумать, что вам нужна коллекция коллекций строк.

Правильно ли я понимаю ваш вопрос? Если да, то ваше упоминание о коллекции коллекции строк неверно.

На самом деле вам нужна коллекция StatOperations, в которой каждая StatOperation должна иметь коллекцию строк. Именно так у вас и было, как показано в ваших классах выше.

Чтобы добиться прогресса, я предлагаю вам отредактировать ваш вопрос и указать, где именно вы застряли после исправления привязки, как предложил AndyG.

0
ответ дан 3 December 2019 в 06:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: