Фон
Существует ListView, который содержит 2 столбца: Столбец файла (строка) и Столбец таблицы (ComboBox).
- У меня есть незафиксированныйколичество ComboBox (от 1 до бесконечности), которое зависит от количества столбцов в файле (это « ImportColumns », чтобы избежать путаницы).
- В списке есть столбцыпрограмма (от 2 до бесконечности). Наименьший случай выглядит следующим образом: «- Нет -», «1». Но это может быть также "- None -", "col1", "element2", "any name", ..., "item99999". Это « WorksheetColumns ».
- Значения ImportColumns и WorksheetColumns полностью не связаны: это могут быть 1: 2, 1: 200, 200: 25 и т. Д.
- Каждый ComboBox имеет общий раскрывающийся список WorksheetColumns. В этом списке «- None -» используется по умолчанию и может использоваться всеми ComboBoxами. Тем не менее, все остальные элементы могут быть выбраны только одним ComboBox за раз.
Например, список "- None -", "1", "2", "3", "4 "," 5 "," 6 "," 7 "," 8 "... Когда каждый ComboBox начинается с" - None - ", каждый ComboBox имеет все элементы списка на выбор. Но когда ComboBox выбирает, например, «1», все остальные ComboBox больше не имеют его в своем раскрывающемся списке. Если «1» затем переключается на что-либо еще, ComboBoxes может снова выбрать его. Таким образом, только не выбранные элементы и «- Нет -» должны отображаться в раскрывающемся списке.
Каждый WorksheetItem имеет свойства, такие как ID (int), Имя (строка) и Выбранный (bool).
Последнее и самое важное: ComboBox, который выбрал, например, "1", должен по-прежнему иметь "1" в своем раскрывающемся списке .
Для суммированияв кратком примере , ComboBox - это "BOY", WorksheetColumns - это "girl". Представьте себе, что BOY1 выбирает девушку: он может быть одиноким ("- None -"), выбрать girl1 (потому что она не CURRENTLY , выбранная любым BOY), girl2 (то же самое), но не girl3 (потому что онабыл выбран BOY2). В то же время, BOY2 может стать одиноким ("- None -"), переключиться на girl1 или girl2, или остаться с girl3 . Задача состоит в том, чтобы включить girl3 в список параметров только для BOY2.
Поскольку число ComboBox точно так же не определено, как WorksheetColumns, я не могу создавать переменные в XAML или C #.
Ранее
Я посоветовал добавить метод в класс, который содержит WorksheetItems, чтобы получить вложенную коллекцию WorksheetItems. Метод возвращает все невыбранные элементы, элемент с идентификатором, равным 0, и элемент, выбранный текущим ComboBox (заданный аргументом keepColumn):
public List<WorksheetColumn> GetWorksheetColumnHeaders(int keepColumn)
{
return WorksheetColumns.Where(header => header.ID == 0 || header.Selected == false || header.ID == keepColumn).ToList();
}
Проблемаесть: я не знаю, где вызвать этот метод. Я читал, что невозможно вызвать метод из XAML, но результат метода должен быть установлен как ItemsSource для нескольких ComboBox (каждый из них должен иметь немного разные ItemsSource из-за того аргумента keepColumn, который сохраняет WorksheetItem выбраннымэтот самый ComboBox - это и есть цель).
У меня есть событие XAML, ComboBox_SelectionChanged и OnWorksheetItemPropertyChanged (происходит, когда изменяется «Выбранное»).
Код
Прямо сейчас мой XAML использует свойство, которое не возвращает необходимый элемент, вместо метода:
<ListView Grid.Row="0" Name="listView" IsSynchronizedWithCurrentItem="True" SelectionMode="Single" Margin="10" ItemsSource="{Binding ImportColumns}" >
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn Header="File column" DisplayMemberBinding="{Binding FileColumnHeader}"/>
<GridViewColumn Header="Worksheet column" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox VerticalAlignment="Center" DataContext="{Binding DataContext,RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" ItemsSource="{Binding ListOfWorksheetColumns.UnselectedWorksheetColumns, UpdateSourceTrigger=PropertyChanged}" SelectionChanged="ComboBox_SelectionChanged" SelectedIndex="0">
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Моя основная ViewModel :
public class ImportManagerViewModel : BaseViewModel
{
public List<ImportColumn> ImportColumns { get; set; }
public ListOfWorksheetColumnHeaders ListOfWorksheetColumns { get; set; }
public bool IsAnyColumnImported
{
get;
set;
}
public void OnImportItemPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
IsAnyColumnImported = ImportColumns.Any(x => x.TargetColumnIndex != 0);
}
public void OnWorksheetItemPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
ListOfWorksheetColumns.UnselectedWorksheetColumns = new ObservableCollection<WorksheetColumn>(ListOfWorksheetColumns.WorksheetColumns.Where(header => header.ID == 0 || header.Selected == false /*|| header.ID == 1*/));
}
}
My ListOfWorksheetColumnHeaders класс (содержит коллекцию, вложенную коллекцию и метод):
public class ListOfWorksheetColumnHeaders : BaseViewModel
{
public ObservableCollection<WorksheetColumn> WorksheetColumns { get; set; } = new ObservableCollection<WorksheetColumn>();
public ObservableCollection<WorksheetColumn> UnselectedWorksheetColumns
{
get;
set;
}
public List<WorksheetColumn> GetWorksheetColumnHeaders(int keepColumn)
{
return WorksheetColumns.Where(header => header.ID == 0 || header.Selected == false || header.ID == keepColumn).ToList();
}
}
My WorksheetColumn class :
public class WorksheetColumn : BaseViewModel
{
public int ID;
public string ColumnName { get; set; }
public bool Selected
{
get;
set;
}
public override string ToString()
{
return ColumnName;
}
}
На данный момент
Единственное, что мне нужно - заставить выбранный WorksheetItem оставаться в выпадающем списке ComboBox, который его выбрал. В противном случае ComboBox немедленно теряет этот элемент из раскрывающегося списка, поскольку его свойство «Выбрать» становится true . Не важно: после того, как он больше не выбран ComboBox, его свойство «Выбрать» становится false , и оно появляется в списке, но ComboBox в настоящий момент ничего не выбрал;другими словами, если вы выберете что-либо, это просто очистит выделение в выпадающем списке.