-1

我需要创建一个 UI,它允许我从一个列表框中选择条目并在运行时将其添加到另一个列表框中。现在,listbox1 可能包含组合框和复选框作为项目。例如,如果我在 listbox1 中添加一个名为 Quarter 的组合框,其值为“Q1、Q2、Q3、Q4”作为项目,并在其中选择条目 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);
    }
4

1 回答 1

1

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

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

在此处输入图像描述

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

ListItemViewModel(“基础”之一):

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

BoolListItemViewModel(用于复选框):

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

SelectableListItemViewModel(用于组合框):

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);
        }
    }
}

这是“主”视图模型,它包含 2 个列表和Commands(按钮操作)

 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.

我正在使用ViewModelBase来自MVVM LightDelegateCommand来自WPFTutorial.net的。您可以将我的代码复制并粘贴到 a 中File -> New Project -> WPF Application并自己查看结果(您还需要上面链接中的这两个类)

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

于 2013-03-06T18:21:10.647 回答