【问题标题】:An ObservableCollection of StackPanel as ItemsSource of ComboBox in WPFWPF 中作为 ComboBox 的 ItemsSource 的 StackPanel 的 ObservableCollection
【发布时间】:2014-08-07 04:54:51
【问题描述】:

我在将 ObservableCollection 作为 ItemsSource 绑定到组合框时遇到问题(此组合框位于包含一些行的列表视图中)。 我关注了A collection of StackPanel as ItemsSource of ComboBox,但没有得到任何解决问题的线索。

问题:

  1. 我能够将项目添加到表单顶部的组合框。
  2. 我创建了一个包含 3 个文本块和 1 个组合框的列表视图。
  3. 我成功地为列表视图中的文本块填充数据。
  4. 但问题在于组合框。第一次,它显示 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


【解决方案1】:

HighCore,非常感谢您提供的链接。我有现有的实现并向其中添加组合框。

我也觉得后面的方法不好。我一定会看看你提供的和 pushpraj 建议的替代方案。

回答: 我认为在其他组合框中引用对象将起作用,直到项目存在于该组合框中。但是我需要为我正在创建的到达组合框以及该组合框中的每个条目创建矩形和文本块。

所以我当然需要在 foreach 循环中执行此操作。 此外,一旦我这样做了,我可以使用 SelectedIndex 引用整数和 SelectedItem 到 sp(该类中的单个堆栈面板)。

这种方法不好遵循,但可能对某人有帮助。

谢谢。

【讨论】:

    猜你喜欢
    • 2012-02-21
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 2015-04-07
    • 2014-05-25
    • 2014-01-26
    • 1970-01-01
    相关资源
    最近更新 更多