【发布时间】:2019-10-15 05:34:53
【问题描述】:
背景
有一个 ListView 包含 2 列:文件列(字符串)和工作表列(组合框)。
- 我的 ComboBox 数量不固定(从 1 到无穷大),这取决于文件中的列数(这些是“ImportColumns”以避免混淆)。
- 程序中有一个列列表(从 2 到无穷大)。最小的情况如下:“-无-”,“1”。但它也可以是“-None-”、“col1”、“element2”、“any name”、...、“item99999”。这些是“WorksheetColumns”。
- ImportColumns 和 WorksheetColumns 的计数完全不相关:可以是 1:2、1:200、200:25 等。
- 每个 ComboBox 都有一个 common 下拉列表的 WorksheetColumns。在此列表中,“-无-”是默认值,甚至可以被所有 ComboBox 采用。但是,所有其他项目一次只能由 1 个 ComboBox 选择。
例如,列表为“-无-”、“1”、“2”、“3”、“4”、“5”、“6”、“7”、“8”...时每个 ComboBox 都以“- None -”开头,每个 ComboBox 都有所有列表项可供选择。但是当一个组合框选择例如“1”时,所有其他组合框不再在其下拉列表中包含它。如果“1”然后切换到其他任何东西,ComboBoxes 可以再次选择它。因此,只有未选择的项目和“-无-”必须显示在下拉列表中。
每个 WorksheetItem 都具有 ID (int)、Name (string) 和 Selected (bool) 等属性。
最后也是最重要的:选择例如“1”的 ComboBox 的下拉列表中仍应包含“1”。
总结为一个简短的例子,ComboBoxes 是“BOY”,WorksheetColumns 是“girl”。想象一下 BOY1 选择女朋友:他可以是单身(“-无-”),选择 girl1(因为她没有CURRENTLY被任何 BOY 选择),girl2(相同),但不是 girl3(因为她被BOY2选中)。同时,BOY2可以选择单身(“-无-”),切换到girl1或girl2,或留在girl3。任务是将girl3 包含在仅适用于BOY2 的选项列表中。
由于 ComboBox 的数量与 WorksheetColumns 一样未定义,因此我无法在 XAML 或 C# 中创建变量。
以前
我是advised 将一个方法放入包含 WorksheetItems 的类中以获取 WorksheetItems 的子集合。该方法返回所有未选中的项目,一个ID等于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 到多个 ComboBoxes(它们中的每一个都必须有一点不同的 ItemsSource,因为“keepColumn”参数保持 WorksheetItem 选择这个 ComboBox - 这就是目标)。
我有 XAML、ComboBox_SelectionChanged 事件和 OnWorksheetItemPropertyChanged(在“Selected”发生更改时发生)。
代码
现在我的 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*/));
}
}
我的 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();
}
}
我的WorksheetColumn 类:
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 会立即从下拉列表中丢失此项,因为它的“Select”属性变为 true。 不重要:不再被ComboBox选中后,其“Select”属性变为false,出现在列表中但ComboBox当前没有选中任何内容;换句话说,如果您选择任何内容,它只会清除组合框的选择。
【问题讨论】:
-
你所听到的叫做绑定。没有人可以在这里解释它,因为它太宽泛了。但是请看docs.microsoft.com/en-us/dotnet/framework/wpf/data/…。浏览所有子页面。
-
@NawedNabiZada 我知道绑定是什么。我的 ItemsSource 已绑定
-
那么在这种情况下:它们中的任何一个都是正确的吗?,不,它们不是。删除选择更改的项并绑定您选择的项目。如果您有按钮,请使用命令
-
仍然值得通过该链接,阅读所有内容。完成后,还要检查一下:wintellect.com/model-view-viewmodel-mvvm-explained。你会喜欢在 WPF 中编程
-
@NawedNabiZada 我已经更新了这个问题。请,看看你有没有新的建议
标签: c# wpf xaml combobox itemssource