【发布时间】:2014-08-07 04:54:51
【问题描述】:
我在将 ObservableCollection 作为 ItemsSource 绑定到组合框时遇到问题(此组合框位于包含一些行的列表视图中)。 我关注了A collection of StackPanel as ItemsSource of ComboBox,但没有得到任何解决问题的线索。
问题:
- 我能够将项目添加到表单顶部的组合框。
- 我创建了一个包含 3 个文本块和 1 个组合框的列表视图。
- 我成功地为列表视图中的文本块填充数据。
- 但问题在于组合框。第一次,它显示 ListView 中每一行的所有项目。一旦我选择项目或再次单击组合框以查看项目,我的列表就会消失。列表视图行中只有一个组合框显示所有项目。其他组合框显示为空白。
另外,我试图保存所选项目的索引并在下次显示所选面板。但是我不知道如何将 stackpanel 与 selecteditem 和 selecteditemvalue 绑定。
我尝试了许多将项目直接绑定到列表视图中的组合框的方法。但没有任何效果。请求某人帮助我。
具体代码如下:
我有如下 XAML:
<Grid>
<Grid Height="40">
<ComboBox x:Name="cbList" />
</Grid>
<Grid Margin="0,56,0,168"></Grid>
<ListView x:Name="lvFirst" Margin="0,195,0,12">
<ListView.View>
<GridView >
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Width="50" x:Uid="tbListView1" Text="{Binding FirstName}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Width="50" x:Uid="tbListView2" Text="{Binding LastName}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Width="50" x:Uid="tbListView1" Text="{Binding ID}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox Width="100" x:Uid="cbListView" ItemsSource="{Binding Path=SPForComboBox}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
在后面的代码中,我有一个 Contact 类,如下所示:
public class Contact : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void Notify(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
private string _fn;
private string _ln;
public string FirstName
{
get
{ return _fn; }
set
{ _fn = value; Notify("FirstName"); }
}
public string LastName
{
get
{ return _ln; }
set
{ _ln = value; Notify("LastName"); }
}
private int _id;
public int ID
{
get { return _id; }
set { _id = value; Notify("ID"); }
}
public StackPanel sp;
public override string ToString()
{
return FirstName + " " + LastName;
}
private ObservableCollection<StackPanel> _sp;
public ObservableCollection<StackPanel> SPForComboBox
{
get { return _sp; }
set { _sp = value; Notify("SPForComboBox"); }
}
}
为了填充 cbList 项,我在 Initialization() 函数之后反复调用以下函数:
private void AddColours(string name, byte hexcolor)
{
//Add this ShiftType to Combo box
SolidColorBrush rectangleBrush = new SolidColorBrush();
Color color = new Color();
color.A = hexcolor;
rectangleBrush.Color = color;
System.Windows.Controls.StackPanel stkPanel = new StackPanel(); //stack panel to hold rectangle + text
stkPanel.Orientation = Orientation.Horizontal;
cbList.Items.Add(stkPanel);
Rectangle colorRect = new Rectangle(); //rectangle showing colour for shift
colorRect.Height = 12;
colorRect.Width = colorRect.Height;
colorRect.Fill = rectangleBrush;
stkPanel.Children.Add(colorRect);
System.Windows.Controls.TextBlock cboText = new TextBlock(); //Name of shift
cboText.Text = name;
cboText.Margin = new Thickness(5, 5, 5, 5);
stkPanel.Children.Add(cboText);
}
在主窗口类中,我创建了一个 ObservableCollection 对象作为公共静态(对象名称是联系人)。
public static ObservableCollection<Contact> contacts = new ObservableCollection<Contact>();
在 Initialization() 函数之后,我将按如下方式填充联系人:
AddColours("First", 100);
AddColours("Second", 50);
AddColours("Third", 20);
AddColours("Fourth", 0);
AddColours("Fifth", 80);
Contact c1 = new Contact();
c1.FirstName = "Digo";
c1.LastName = "Maradona";
c1.ID = 0;
c1.SPForComboBox = new ObservableCollection<StackPanel>();
foreach (StackPanel sp in cbList.Items)
{
c1.SPForComboBox.Add(sp);
}
Contact c2 = new Contact();
c2.FirstName = "Brian";
c2.LastName = "Lara";
c2.ID = 1;
c2.SPForComboBox = new ObservableCollection<StackPanel>();
foreach (StackPanel sp in cbList.Items)
{
c2.SPForComboBox.Add(sp);
}
Contact c3 = new Contact();
c3.FirstName = "Sachin";
c3.LastName = "Tendulkar";
c3.ID = 2;
c3.SPForComboBox = new ObservableCollection<StackPanel>();
foreach (StackPanel sp in cbList.Items)
{
c3.SPForComboBox.Add(sp);
}
contacts.Add(c1);
contacts.Add(c2);
contacts.Add(c3);
lvFirst.ItemsSource = contacts;
【问题讨论】:
-
因为任何孩子只能有 1 个父级,并且由于
SPForComboBox包含 UIElements,即 StackPanel,因此会导致问题,并且只有最后一个组合显示项目。您可能会避免在视图模型中使用 UIElements,即。绑定源,并使用数据模板呈现项目。 -
嗨,谢谢。但是我不能使用其他方法,因为我需要更改很多地方。我通过在 foreach 循环中再次创建每个孩子并添加到 SPForComboBox 来解决问题。现在数据是一致的,我可以一直看到它们。但现在的问题是保存和检索组合框中的选定项目。我可以选择并保存该项目,但是当我加载它时,它显示为空白。我使用 SelectedValue={Binding Path=SP"} SelectedValuePath="ID" 但没有显示任何内容。如果我遗漏了什么,请告诉我。谢谢。
-
我认为你不需要 Notify("SPForComboBox") 一个 observablecollection 内置的通知。
-
我没有看到任何名为
SP的属性,您是否在这里遗漏了什么?您可以发布工作样本吗?我可以尝试在那里修复吗? -
我很好奇你用一个完全正确的答案回答了一个完全错误的问题,并且使用了问题中的代码而不是阅读答案。
标签: wpf listview combobox observablecollection