如何在列表框中显示多个词典项目 [英] How to show multiple Dictionary items in ListBox
问题描述
我的代码有两个ListBox(LeftListBox
和RightListBox
)和一个TextBox.这些列表框在它们之间传输项目.文本框显示一个数字,该数字与RightListBox
中的SelectedItem相对应(例如,选择T1
时显示10
,选择T2
时显示20
,依此类推).
My code has two ListBoxes (LeftListBox
and RightListBox
) and one TextBox. Those ListBoxes transfer the items between the them. The TextBox shows a number, which corresponds to the SelectedItem in RightListBox
(e.g., when T1
is selected, it shows 10
, when T2
is selected, it shows 20
, and so on).
我刚刚做到了!! ...但是那些列表框只显示三分之一中的第一个词典项 ...我该如何显示所有这些?
I've just made it!! ... but those ListBoxes show only the 1st Dictionary item out of three ... How can I show all of them?
这是我的代码:
MainWindow.xaml
MainWindow.xaml
<Window x:Class="ListBoxMoveAll.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ListBoxMoveAll"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="600">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListBox x:Name="LeftListBox" Grid.Row="0" Grid.RowSpan="3" Grid.Column="0"
ItemsSource="{Binding LeftListBoxItems}" DisplayMemberPath="Key" SelectedValuePath="Value"
SelectionMode="Extended" Margin="0,10"/>
<StackPanel Grid.Column="1" Grid.Row="0" VerticalAlignment="Center">
<Button Content="Add" x:Name="Add_Button" Click="Add_Button_Click"/>
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="2" VerticalAlignment="Center">
<Button Content="Remove" x:Name="Remove_Button" Click="Remove_Button_Click"/>
</StackPanel>
<ListBox x:Name="RightListBox" Grid.Row="0" Grid.RowSpan="3" Grid.Column="2"
ItemsSource="{Binding RightListBoxItems}" DisplayMemberPath="Key" SelectedValuePath="Value"
SelectionMode="Extended" Margin="0,10"/>
<StackPanel Grid.Column="4" Grid.Row="1" Grid.RowSpan="1" Margin="0,10">
<TextBox Text="{Binding SelectedValue.Step, ElementName=RightListBox}"/>
</StackPanel>
</Grid>
</Window>
MainWindow.xaml.cs
MainWindow.xaml.cs
using ListBoxMoveAll.Model;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
namespace ListBoxMoveAll
{
public partial class MainWindow : Window
{
public ObservableCollection<Dictionary<string, Graph>> LeftListBoxItems { get; }
= new ObservableCollection<Dictionary<string, Graph>>();
public ObservableCollection<Dictionary<string, Graph>> RightListBoxItems { get; }
= new ObservableCollection<Dictionary<string, Graph>>();
public MainWindow()
{
InitializeComponent();
DataContext = this;
Dictionary<string, Graph> Dic = new Dictionary<string, Graph>();
Dic.Add("T1", new Graph(10));
Dic.Add("T2", new Graph(20));
Dic.Add("T3", new Graph(30));
LeftListBoxItems.Add(Dic);
// Yes! There are three items in Dic!
foreach (var item in Dic)
{
MessageBox.Show(item.ToString());
}
}
private void Add_Button_Click(object sender, RoutedEventArgs e)
{
//foreach (TestModel item in LeftListBox.SelectedItems.OfType<TestModel>().ToList())
foreach (Dictionary<string, Graph> item
in LeftListBox.SelectedItems.OfType<Dictionary<string, Graph>>().ToList())
{
LeftListBoxItems.Remove(item);
RightListBoxItems.Add(item);
}
}
private void Remove_Button_Click(object sender, RoutedEventArgs e)
{
foreach (Dictionary<string, Graph> item
in RightListBox.SelectedItems.OfType<Dictionary<string, Graph>>().ToList())
{
RightListBoxItems.Remove(item);
LeftListBoxItems.Add(item);
}
}
}
}
Model/Graph.cs
Model/Graph.cs
namespace ListBoxMoveAll.Model
{
public class Graph
{
public Graph(int step) { Step = step; }
public int Step { get; set; }
}
}
由于foreach语句显示Dic中包含三个项目,因此我认为我的XAML存在问题,但我无法弄清楚.你们可能知道问题所在.抱歉,这是一个非常基本的问题.谢谢您.
Since the foreach statement shows that there are three items in Dic, I think my XAML has an issue, but I cannot figure that out. You guys might know what the issue is. Sorry if this is a very basic question ... Thank you in advance.
新发现:我为LeftListBoxItems
添加了另一个foreach语句:
New Discovery: I've added another foreach statement for LeftListBoxItems
:
foreach (var item in LeftListBoxItems)
{
MessageBox.Show(item.ToString());
}
...输出仅一次,内容为:
... The output is only once and the content is:
System.Collections.Generic.Dictionary`2[System.String,ListBoxMoveAll.Model.Graph]
这是什么意思?
推荐答案
由于使用的是数据绑定,因此正确"的处理方式是将文本和项目都包装在视图模型中:
Since you're using data binding the "proper" way to handle this is to wrap both the text and item in a view model:
public class GraphViewModel
{
public string Text { get; }
public Graph Graph { get; }
public GraphViewModel(string text, Graph graph) => (Text, Graph) = (text, graph);
}
无需字典,您的收藏集可以改用以下类型:
No need for the dictionary, your collections can use this type instead:
public ObservableCollection<GraphViewModel> LeftListBoxItems { get; } = new ObservableCollection<GraphViewModel>();
public ObservableCollection<GraphViewModel> RightListBoxItems { get; } = new ObservableCollection<GraphViewModel>();
类似地,将项目添加到字典中只是为了随后将它们立即添加到集合中,没有任何意义,只需将它们直接添加到集合中即可:
Similarly, there's no point in adding items to a dictionary only to add them to the collection immediately afterwards, just add them to the collection directly:
LeftListBoxItems.Add(new GraphViewModel("T1", new Graph(10)));
LeftListBoxItems.Add(new GraphViewModel("T2", new Graph(20)));
LeftListBoxItems.Add(new GraphViewModel("T3", new Graph(30)));
对每个按钮处理程序进行了较小的更改:
A minor change to each of your button handlers:
foreach (var item in LeftListBox.SelectedItems.Cast<GraphViewModel>().ToList())
... and ...
foreach (var item in RightListBox.SelectedItems.Cast<GraphViewModel>().ToList())
最后,将列表框DisplayMemberPath
属性绑定到Text
并摆脱SelectedValuePath
:
Finally, bind your list box DisplayMemberPath
properties to Text
and get rid of the SelectedValuePath
:
<ListBox x:Name="LeftListBox" Grid.Row="0" Grid.RowSpan="3" Grid.Column="0"
ItemsSource="{Binding LeftListBoxItems}" DisplayMemberPath="Text"
SelectionMode="Extended" Margin="0,10"/>
<ListBox x:Name="RightListBox" Grid.Row="0" Grid.RowSpan="3" Grid.Column="2"
ItemsSource="{Binding RightListBoxItems}" DisplayMemberPath="Text"
SelectionMode="Extended" Margin="0,10"/>
这类似于Genos Loser的第二个示例,但是视图模型比KeyValuePair更具有类型安全性,并且如果需要的话,在以后添加INPC也会更容易.
This is similar to Genos Loser's 2nd example, but a view model is more typesafe than a KeyValuePair and it's also easier to add INPC to later if you need to.
这篇关于如何在列表框中显示多个词典项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!