我需要创建一个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);
}
答案 0 :(得分:1)
这是一个满足您需求的WPF解决方案。我发布它是因为你告诉我它可能对你有用。它大大超过了你希望在winforms中实现的任何东西,这是一种非常有限且过时的技术。
这就是我在屏幕上的样子:
我使用一些简单的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中的ViewModelBase
和WPFTutorial.net中的DelegateCommand
。您可以在File -> New Project -> WPF Application
中复制并粘贴我的代码,并亲自查看结果(您还需要上述链接中的这两个类)
如果您需要将其集成到现有的winforms应用程序中,则需要ElementHost