【问题标题】:How to use Selected Item in a Custom Collection如何在自定义集合中使用选定项目
【发布时间】:2013-10-10 18:21:23
【问题描述】:

我有一个程序可以更改 comboBox 中显示的项目集合。我之前在this question 中讨论过它。无论如何,我现在正在使用自定义集合,因为observableCollection 没有selectedItem 属性。自定义集合中有一个 selectedItem 属性,但我只是不确定如何设置它以便保存数据。

自定义集合类

public class MyCustomCollection<T>: ObservableCollection<T>
{
    private T _mySelectedItem;

    public MyCustomCollection(IEnumerable<T> collection) : base(collection) { }

    public T MySelectedItem
    {
        get { return _mySelectedItem; }
        set
        {
            if (Equals(value, _mySelectedItem)) return;
            _mySelectedItem = value;
            OnPropertyChanged(new PropertyChangedEventArgs("MySelectedItem"));
        }
    }
}

ViewModel - 我在 comboBox 中更改集合并为每个集合设置 selectedItem

//Property for the selected command in the LIST BOX
//**For clarity: the collection in the comboBox is changed based on what is
//selected in the list box
public string SelectedCommand
{
    get { return _selectedCommand; }
    set
    {
        _selectedCommand = value;
        NotifyPropertyChange(() => SelectedCommand);

        if (SelectedCommand == "1st Collection of type A")
        {
            ComboBoxEnabled = true;
            ComboBoxList = new MyCustomCollection<string>(collectionA);
            //collectionA.MySelectedItem = ??(What would I put here?) 
        }
        if (SelectedCommand == "2nd Collection of type A")
        {
            ComboBoxEnabled = true;
            ComboBoxList = new MyCustomCollection<string>(collectionA);
            //collectionA.MySelectedItem = ??(What would I put here?)
        }
    }
}

如何为我创建并添加到comboBox 的每个新集合分配一个值给MySelectedItem?这样,每当我切换到 comboBox 中的不同集合时,selectedItem 就会显示出来。

更新

我的收藏现在设置为ObservableCollection&lt;string&gt;

ListBoxComboBox 的 XAML

<ListBox ItemsSource="{Binding Model.CommandList}" SelectedItem="{Binding Model.SelectedCommand}" ... />

<ComboBox ItemsSource="{Binding Model.ComboBoxList}" SelectedItem="{Binding Model.SelectedOperation}"  ... />

**ListBox 下的新 SelectedCommand 属性:

public string SelectedCommand
{
    get { return _selectedCommand; }
    set
    {
        _selectedCommand = value;
        NotifyPropertyChange(() => SelectedCommand);

        switch (SelectedCommand)
        {
            case "Collection A":
                {
                    ComboBoxList = CollectionA;
                    break;
                }
            case "Collection B":
                {
                    ComboBoxList = CollectionB;
                    break;
                }
        }
        NotifyPropertyChange(() => ComboBoxList);
    }
}

程序仍然没有保留为每个集合选择的selectedItem我一定是忘记了,或者不明白什么。

【问题讨论】:

  • 不确定我理解您为什么决定实施自定义 ObservableCollection。您可以将 ComboBox 绑定到集合以及选定的项目 &lt;ComboBox ItemsSource="{Binding someCollection}" SelectedItem="{Binding someItem}"/&gt;
  • 我知道,而且行得通。但是,comboBox 的集合和selectedItem 取决于在listBox 中选择的命令。所以selectedItem 不依赖于它存在的每个窗口的一个集合。
  • 所以让我直截了当地说,你想要一个ComboBox,当你更改它的集合时(我假设通过选择列表框中的某些项目),它的SelectedItem 变成......什么?
  • 是的。 selectedItem 将是用户选择的任何内容。所以一开始什么都不会。
  • 然后只需将您的组合框绑定到一个集合,将其绑定一个 selectedItem,然后在您的列表框的更改命令上更改集合...等等,我将在答案中发布示例代码.. .

标签: c# wpf combobox observablecollection selecteditem


【解决方案1】:

您不需要自定义集合来绑定所选项目。 以下是如何完成此操作的示例:

   <StackPanel>
        <!-- your listbox -->
        <ListBox x:Name="listbox">
            <sys:String>Fruits</sys:String>
            <sys:String>Vegetables</sys:String>
            <sys:String>Others</sys:String>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding ElementName=listbox, Path=SelectedItem}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ListBox>

        <!-- your combo box -->
        <ComboBox ItemsSource="{Binding Items}" SelectedItem="{Binding CurrentItem}"/>
    </StackPanel>

xaml 包含一个带有项目(在本例中为简单字符串)的 ListBox 和一个命令 SelectionChangedCommand,只要列表中的选择发生更改,就会调用该命令。

这里是 ViewModel

public class MainWindowViewModel : NotificationObject
{
    // your collections
    private ObservableCollection<string> fruits;
    private ObservableCollection<string> vegetables;
    private ObservableCollection<string> others;

    public MainWindowViewModel()
    {
        fruits = new ObservableCollection<string>
            {
                "Apple", "Banana"
            };
        vegetables = new ObservableCollection<string>
            {
                "Tomato", "Cabbage"
            };
        others = new ObservableCollection<string>
            {
                "Pizza", "Steak"
            };

        SelectionChangedCommand = new DelegateCommand<string>(item =>
            {
                // When user selects item in the listbox change the collection of your comboBox
                switch (item)
                {
                    case "Fruits":
                        {
                            Items = fruits;
                            break;
                        }
                    case "Vegetables":
                        {
                            Items = vegetables;
                            break;
                        }
                    case "Others":
                        {
                            Items = others;
                            break;
                        }
                }

                // Raise property change to make combobox update
                RaisePropertyChanged(() => Items);
            });               
    }

    // the collection currently displayed in the comboBox
    public ObservableCollection<string> Items { get; set; }

    // The selected item of the combobox
    public string CurrentItem { get; set; }

    public DelegateCommand<string> SelectionChangedCommand { get; set; }
}

ViewModel 包含:

  1. 作为私有成员的多个集合(fruitsvegetablesothers

  2. Items 是一个集合属性,表示基于 ListBox` 中的选择的 ComboBox 的当前项。

  3. CurrentItem 属性绑定到 ComboBoxSelectedItem

  4. SelectionChangedCommand 调用时,会根据给定参数(ListBox 中的选定项)更改集合。

请注意,此示例使用Prism 框架,但您可以使用任何支持命令的MVVM framework 来实现此目的。

如果您没有使用任何框架,只需将“命令”中的代码视为每当ListBox 的选择项发生更改时执行的代码(但是您已经实现了)。

希望对你有帮助

【讨论】:

  • 你必须使用某种框架,因为我只是使用 C#->WPF。我的 xaml 中没有 Interaction
  • 所谓的SelectionChangedCommand让我一头雾水,其实是一个叫SelectionChangedEventHandlerevent handler
  • @Ericafterdark 是的。很抱歉没有提到它。我使用Prism 框架。如果您没有使用任何框架(顺便说一句,您应该这样做),只需将命令代码放在您的 SelectedCommand setter 中,我假设每当用户更改 ListBox 的 selecteItem 时都会调用它
  • 是的。好的,这更有意义,这就是我试图处理它的地方,正如您在问题中看到的那样。
  • @Ericafterdark 您是否能够在您的viewModel 中检测到您的ListBox 的选择更改?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多