Ленивая инициализация параметра! Помимо всех предыдущих ответов (стратегическая модель, шаблон "наблюдатель", и т.д.), делегаты позволяют Вам обрабатывать ленивую инициализацию параметров. Например, предположите, что у Вас есть функциональная Загрузка (), который занимает довольно много времени и возвращает определенный DownloadedObject. Этот объект используется устройством хранения данных в зависимости от определенные условия. Как правило, Вы были бы:
storage.Store(conditions, Download(item))
Однако с делегатами (более точно, лямбды) можно сделать следующее путем изменения подписи хранилища так, чтобы это получило Условие и Func< Объект, DownloadedObject> и используйте его как это:
storage.Store(conditions, (item) => Download(item))
Поэтому устройство хранения данных только оценит делегата при необходимости, выполняя загрузку в зависимости от Условий.
Во-первых, это должно быть легко... во-вторых, почему вы строите (и связываете) столбцы в 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;
}
Результаты:
Я думаю, ошибка в том, как вы сделали привязку. Когда вы определяете столбец, привязка связана с объектом, который представлен определенной строкой. Насколько я понимаю, у вас есть 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. Удачи!
РЕДАКТИРОВАТЬ Извините, я немного медлителен в полночь :). Вот обновленный ответ. Похоже, отличная статья Винсента Сибала WPF DataGrid - DataGridComboBoxColumn v1 Intro отвечает на ваш вопрос. Это так?
Для исправления ошибки ItemsSource Binding Error используйте форму:
BindingOperations.SetBinding(new DataGridComboBoxColumn(), DataGridComboBoxColumn.ItemsSourceProperty, new Binding("Data"));
Очевидно, что вы не можете сделать это в инициализаторе, поэтому вам придется немного пошевелить объявлениями, но это должно позаботиться об этой ошибке в вашем обновлении.
Частично - я думаю, что в ваших словах есть путаница. Вы сказали, что вам нужна коллекция строк в каждой строке, чтобы комбобокс мог показывать разные строки для разных строк. Однако для того, чтобы в комбобоксе отображался набор строк, вам нужна только коллекция строк в каждой строке, а не коллекция коллекций строк.
Теперь, поскольку вам нужна коллекция строк на строку, вы можете подумать, что вам нужна коллекция коллекций строк.
Правильно ли я понимаю ваш вопрос? Если да, то ваше упоминание о коллекции коллекции строк неверно.
На самом деле вам нужна коллекция StatOperations, в которой каждая StatOperation должна иметь коллекцию строк. Именно так у вас и было, как показано в ваших классах выше.
Чтобы добиться прогресса, я предлагаю вам отредактировать ваш вопрос и указать, где именно вы застряли после исправления привязки, как предложил AndyG.