我已经定义了一个ListView
,其中每个项目都以只读方式显示(即仅限选择,不是TextBox
)ComboBox
(根据ItemTemplate
)。
可以从这些组合框中选择一个可能的项目列表。但需要注意的是,一次两个组合框中不能选择任何项目。为了确保这一点,一旦在其中一个组合框中选择了一个项目,它必须从所有其他组合框中删除(显然除了选择它的那个),并且一旦取消选择它,就必须添加它再次到所有其他组合框。
哦,还有一件事:与完整列表相比,可见项目的顺序不得改变。
我的问题是:我该如何实现这种行为?
我已经尝试了三种可能的解决方案:
ItemTemplate
中包含该控件类;然后,该模板中的组合框将其ItemsSource
属性绑定到助手类的ItemsProvider
属性,该属性应该将现有项目列表,排除项目列表和所选项目绑定在一起。返回该特定组合框的单个枚举项
但是,我在所有关于列表更改的更新通知中都丢失了;我担心我必须对两个输入列表中的NotifyCollectionChangedAction
的所有组合做出单独的反应,并且考虑到有十几种更新方法,我认为这不是正确的方法。ItemsSource
属性。ListViewItem
并检索每个ListViewItem
的组合框以手动刷新项目列表。但是,在加载项目模板后,我找不到访问ListView.ItemContainerGenerator
s的好时机。对于这种情况似乎没有事件,ItemContainerGenerator
是只读的,所以即使ItemContainerGenerator
不是密封的类,我也无法分配我自己的专用OnApplyTemplate
会创建我可以覆盖{{1}}的自定义列表视图项。答案 0 :(得分:0)
我可能会将所有ComboBoxes
绑定到源集合上的不同CollectionViews
,这会过滤掉其他ComboBoxes
的所选项目。如果组合框的选择发生变化,您还需要Refresh
视图。
答案 1 :(得分:0)
如果将列表绑定到ViewModel中的不同列表,并绑定所选项以触发更改这些列表的方法,则可以获得结果。与以下类似。
MainWindow.xaml的Xaml:
<Window x:Class="ComboBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180" />
<ColumnDefinition Width="180" />
<ColumnDefinition Width="180" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="26" />
</Grid.RowDefinitions>
<ComboBox Name="cboOne" Grid.Column="0" Grid.Row="0" ItemsSource="{Binding CboOneList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding CboOneValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></ComboBox>
<ComboBox Name="cboTwo" Grid.Column="1" Grid.Row="0" ItemsSource="{Binding CboTwoList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding CboTwoValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></ComboBox>
<ComboBox Name="cboThree" Grid.Column="2" Grid.Row="0" ItemsSource="{Binding CboThreeList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding CboThreeValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></ComboBox>
</Grid>
</Window>
MainWindow.xaml的代码隐藏:
using System.Windows;
using System.Windows.Controls;
namespace ComboBox {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
this.DataContext = new ComboBoxViewModel();
}
private void cboOne_SelectionChanged(object sender, SelectionChangedEventArgs e) {
}
}
}
视图模型:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace ComboBox {
class ComboBoxViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
List<string> master = new List<string>() { "A", "B", "C", "D", "E", "F" };
#region C'tor
public ComboBoxViewModel() {
RetrieveLists();
}
#endregion
#region Methods
protected void OnPropertyChanged(String propertyName) {
PropertyChangedEventHandler handler = this.PropertyChanged;
if(null != handler) {
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public void RetrieveLists() {
List<string> tempOne = (from a in master
where !a.Equals(CboTwoValue) && !a.Equals(CboThreeValue)
select a).ToList();
CboOneList = tempOne;
List<string> tempTwo = (from a in master
where !a.Equals(CboOneValue) && !a.Equals(CboThreeValue)
select a).ToList();
CboTwoList = tempTwo;
List<string> tempThree = (from a in master
where !a.Equals(CboTwoValue) && !a.Equals(CboOneValue)
select a).ToList();
CboThreeList = tempThree;
}
#endregion
#region Properties
private string cboOneValue = string.Empty;
public string CboOneValue {
get {
return cboOneValue;
}
set {
if(!value.Equals(cboOneValue)) {
cboOneValue = value;
RetrieveLists();
OnPropertyChanged("CboOneValue");
}
}
}
private string cboTwoValue = string.Empty;
public string CboTwoValue {
get {
return cboTwoValue;
}
set {
if(!value.Equals(cboTwoValue)) {
cboTwoValue = value;
RetrieveLists();
OnPropertyChanged("CboTwoValue");
}
}
}
private string cboThreeValue = string.Empty;
public string CboThreeValue {
get {
return cboThreeValue;
}
set {
if(!value.Equals(cboThreeValue)) {
cboThreeValue = value;
RetrieveLists();
OnPropertyChanged("CboThreeValue");
}
}
}
private List<string> cboOneList = new List<string>();
public List<string> CboOneList {
get {
return cboOneList;
}
set {
cboOneList = value;
OnPropertyChanged("CboOneList");
}
}
private List<string> cboTwoList = new List<string>();
public List<string> CboTwoList {
get {
return cboTwoList;
}
set {
cboTwoList = value;
OnPropertyChanged("CboTwoList");
}
}
private List<string> cboThreeList = new List<string>();
public List<string> CboThreeList {
get {
return cboThreeList;
}
set {
cboThreeList = value;
OnPropertyChanged("CboThreeList");
}
}
#endregion
}
}