-1

我已经定义了一个ListView每个项目都以只读方式显示的位置(即仅选择,否TextBoxComboBox(根据ItemTemplate)。

可以从这些组合框中的每一个中选择一个给定的可能项目列表。但是,需要注意的是,不能一次在两个组合框中选择任何项目。为了确保这一点,一旦在其中一个组合框中选择了一个项目,就必须从所有其他组合框中删除它(显然除了它被选中的组合框),一旦它被取消选择,就必须添加它再次到所有其他组合框。

哦,还有一件事:与完整列表相比,可见项目的顺序不得改变。

我的问题是:我怎样才能实现这种行为?

我尝试了三种可能的解决方案:

  • 我编写了一个新的辅助控件类,它通过与外部世界的绑定获取现有项目的完整列表和排除(使用)项目的列表,以及选定项目的属性。我可以将该控制类包含在ItemTemplate; 然后,该模板中的组合框将其ItemsSource属性绑定到ItemsProvider帮助器类的属性,该属性应该将现有项目列表、排除项目列表和选定项目绑定在一起,并返回该特定组合的单个项目枚举盒子。
    然而,我不知何故迷失在所有关于列表更改的更新通知中;我担心我必须单独对所有组合做出反应NotifyCollectionChangedAction在两个输入列表中,并且有十几个更新方法的前景,我认为这不是正确的方法。
  • 我将现有项目的列表更改为存储布尔值以及每个项目的列表,因此我可以将每个项目标记为隐藏或不隐藏。这将减轻我在保持项目顺序的同时拥有排除项目列表的必要性,从而降低了上述组合更改通知的复杂性。
    不幸的是,由于列表本身不会随该解决方案而改变,我不知道如何让依赖属性基础结构ItemsSource在我的帮助程序类中通知我的属性。
  • 我不必使用带有绑定方式的 WPF;我也可以在这里做代码隐藏。因此,我尝试遍历所有ListViewItems 并检索每个组合框以手动刷新项目列表。ListViewItem但是,在加载项目模板后,我找不到访问 s 的好时机。这种情况似乎没有事件,并且ListView.ItemContainerGenerator是只读的,所以即使ItemContainerGenerator不是密封类,我也无法分配我自己的专业ItemContainerGenerator来创建我可以覆盖的自定义列表视图项目OnApplyTemplate
4

2 回答 2

0

我可能会将所有内容绑定ComboBoxes到源集合上的不同CollectionViews对象,这些集合会过滤掉其他对象的选定项目ComboBoxesRefresh如果组合框的选择发生变化,您还需要查看视图。

于 2012-09-25T19:56:50.050 回答
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
}

}

于 2012-09-25T20:26:19.283 回答