如何在列表框中添加combox和其他项?

时间:2013-03-06 16:42:58

标签: c# winforms

我需要创建一个UI,允许我从一个列表框中选择条目,并在运行时将其添加到另一个列表框中。现在,listbox1可能包含组合框和复选框作为项目。   例如,如果我添加一个标记为Quarter的组合框,其值为“Q1,Q2,Q3,Q4”作为listbox1中的项目并选择其中的条目Q1,并单击“添加”按钮,则应将其添加到listbox2 。反之亦然也应该是可能的。这应该可以在运行时进行。如何将组合框和复选框作为项添加到列表框?此外,请建议如果添加 - 删除按钮,我的代码是正确的。

private void MoveListBoxItems(ListBox source, ListBox destination)
    {
        ListBox.SelectedObjectCollection sourceItems = source.SelectedItems;
        foreach (var item in sourceItems)
        {
            destination.Items.Add(item);
        }
        while (source.SelectedItems.Count > 0)
        {
            source.Items.Remove(source.SelectedItems[0]);
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        MoveListBoxItems(listBox1, listBox2);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        MoveListBoxItems(listBox2, listBox1);
    }

1 个答案:

答案 0 :(得分:1)

这是一个满足您需求的WPF解决方案。我发布它是因为你告诉我它可能对你有用。它大大超过了你希望在winforms中实现的任何东西,这是一种非常有限且过时的技术。

这就是我在屏幕上的样子:

enter image description here

我使用一些简单的ViewModel来表示数据:

ListItemViewModel(“基础”):

 public class ListItemViewModel: ViewModelBase
    {
        private string _displayName;
        public string DisplayName
        {
            get { return _displayName; }
            set
            {
                _displayName = value;
                NotifyPropertyChange(() => DisplayName);
            }
        }
    }

BoolListItemViewModel(对于CheckBoxes):

public class BoolListItemViewModel: ListItemViewModel
{
    private bool _value;
    public bool Value
    {
        get { return _value; }
        set
        {
            _value = value;
            NotifyPropertyChanged(() => Value);
        }
    }
}

SelectableListItemViewModel(对于ComboBoxes):

public class SelectableListItemViewModel: ListItemViewModel
{
    private ObservableCollection<ListItemViewModel> _itemsSource;
    public ObservableCollection<ListItemViewModel> ItemsSource
    {
        get { return _itemsSource ?? (_itemsSource = new ObservableCollection<ListItemViewModel>()); }
    }

    private ListItemViewModel _selectedItem;
    public ListItemViewModel SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            _selectedItem = value;
            NotifyPropertyChange(() => SelectedItem);
        }
    }
}

这是“Main”ViewModel,它包含2个列表和Commands(Button操作)

 public class ListBoxSampleViewModel: ViewModelBase
    {
        private ObservableCollection<ListItemViewModel> _leftItems;
        public ObservableCollection<ListItemViewModel> LeftItems
        {
            get { return _leftItems ?? (_leftItems = new ObservableCollection<ListItemViewModel>()); }
        }

        private ObservableCollection<ListItemViewModel> _rightItems;
        public ObservableCollection<ListItemViewModel> RightItems
        {
            get { return _rightItems ?? (_rightItems = new ObservableCollection<ListItemViewModel>()); }
        }

        private DelegateCommand<ListItemViewModel> _moveToRightCommand;
        public DelegateCommand<ListItemViewModel> MoveToRightCommand
        {
            get { return _moveToRightCommand ?? (_moveToRightCommand = new DelegateCommand<ListItemViewModel>(MoveToRight)); }
        }

        private void MoveToRight(ListItemViewModel item)
        {
            if (item != null)
            {
                LeftItems.Remove(item);
                RightItems.Add(item);    
            }
        }

        private DelegateCommand<ListItemViewModel> _moveToLeftCommand;
        public DelegateCommand<ListItemViewModel> MoveToLeftCommand
        {
            get { return _moveToLeftCommand ?? (_moveToLeftCommand = new DelegateCommand<ListItemViewModel>(MoveToLeft)); }
        }

        private void MoveToLeft(ListItemViewModel item)
        {
            if (item != null)
            {
                RightItems.Remove(item);
                LeftItems.Add(item);    
            }
        }
    }

这是Window的整个XAML:

<Window x:Class="WpfApplication4.Window14"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication4"
        Title="Window14" Height="300" Width="300">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:ListItemViewModel}">
            <TextBlock Text="{Binding DisplayName}"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:BoolListItemViewModel}">
            <CheckBox Content="{Binding DisplayName}" IsChecked="{Binding Value}" HorizontalAlignment="Left"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:SelectableListItemViewModel}">
            <ComboBox ItemsSource="{Binding ItemsSource}" SelectedItem="{Binding SelectedItem}"
                      HorizontalAlignment="Stretch" MinWidth="100"/>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListBox ItemsSource="{Binding LeftItems}"
                 x:Name="LeftList"/>

        <StackPanel Grid.Column="1" VerticalAlignment="Center">
            <Button Content="Move to Right" 
                    Command="{Binding MoveToRightCommand}"
                    CommandParameter="{Binding SelectedItem,ElementName=LeftList}"/>
            <Button Content="Move to Left" 
                    Command="{Binding MoveToLeftCommand}"
                    CommandParameter="{Binding SelectedItem,ElementName=RightList}"/>
        </StackPanel>

        <ListBox ItemsSource="{Binding RightItems}"
                 Grid.Column="2" x:Name="RightList"/>
    </Grid>
</Window>

最后,这是Window Code-behind,它只用一些项初始化ViewModel:

   public partial class Window14 : Window
    {
        public Window14()
        {
            InitializeComponent();

            DataContext = new ListBoxSampleViewModel()
                              {
                                  LeftItems =
                                      {
                                          new ListItemViewModel(){DisplayName = "Item1"},
                                          new BoolListItemViewModel() {DisplayName = "Check Item 2", Value = true},
                                          new SelectableListItemViewModel()
                                              {
                                                  ItemsSource =
                                                      {
                                                          new ListItemViewModel() {DisplayName = "Combo Item 1"},
                                                          new BoolListItemViewModel() {DisplayName = "Check inside Combo"},
                                                          new SelectableListItemViewModel()
                                                              {
                                                                  ItemsSource =
                                                                      {
                                                                          new ListItemViewModel() {DisplayName = "Wow, this is awesome"},
                                                                          new BoolListItemViewModel() {DisplayName = "Another CheckBox"}
                                                                      }
                                                              }
                                                      }
                                              }
                                      }
                              };
        }
    }

乍一看,这可能看起来像很多代码......但如果你需要2秒钟来分析它...它只是“简单,简单的属性和INotifyPropertyChanged。这就是你在WPF中编程的方式

我所说的是与你在winforms中习惯的完全不同的范例,但是真正值得学习它的努力。请注意,我的代码中没有任何地方与UI元素进行交互。我只是创建ViewModel结构,让WPF Binding System使用提供的DataTemplates来为我生成用户界面。

我正在使用MVVM Light中的ViewModelBaseWPFTutorial.net中的DelegateCommand。您可以在File -> New Project -> WPF Application中复制并粘贴我的代码,并亲自查看结果(您还需要上述链接中的这两个类)

如果您需要将其集成到现有的winforms应用程序中,则需要ElementHost