C# WPF数据绑定可观察收集<;T>;到数据网格

C# WPF数据绑定可观察收集<;T>;到数据网格,c#,wpf,data-binding,datagrid,C#,Wpf,Data Binding,Datagrid,我试图在一个单独的UserControl中创建DataGrid,其DataContext是T的列表 在代码隐藏中,我创建了一个列表,填充该列表,然后将其发送给UserControl的构造函数,在该构造函数上我有我试图填充的DataGrid UserControl类如下所示 public partial class QuotePreview : UserControl { private static SelectionList previewList = new SelectionLi

我试图在一个单独的UserControl中创建DataGrid,其DataContext是T的列表

在代码隐藏中,我创建了一个列表,填充该列表,然后将其发送给UserControl的构造函数,在该构造函数上我有我试图填充的DataGrid

UserControl类如下所示

public partial class QuotePreview : UserControl
{
    private static SelectionList  previewList = new SelectionList();

    public SelectionList PreviewList
    {
        get { return previewList; }
    }

    public QuotePreview()
    {
        InitializeComponent();
    }

    public QuotePreview(SelectionList selectedOptions)
    {
        InitializeComponent();

        previewList = selectedOptions;

        QuotePreviewDataGrid.DataContext = previewList;
    }
}
Xaml看起来像:

<DataGrid Name="QuotePreviewDataGrid"
          AutoGenerateColumns="False" 
          ItemsSource="{Binding}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Model Number" Binding="{Binding ModelNumber}"/>
        <DataGridTextColumn Header="Description" Binding="{Binding Description}"/>
        <DataGridTextColumn Header="List Price per Unit" Binding="{Binding Price}"/>
    </DataGrid.Columns>
</DataGrid>
我还尝试设置数据上下文和itemsource以及刷新:

QuotePreviewDataGrid.Items.Refresh();
在我的应用程序的其余部分中,我设置为列表框的数据绑定工作得非常好。在列表框中,我将itemsource设置为{Binding},将ListItems绑定设置为{Binding Property}。代码隐藏中设置的列表框的datacontext

这里我的datagrid是以同样的方式设置的,但是由于某些原因,网格内没有显示任何内容

当我通过调试器查看信息流时,我可以看到正在创建的T、SelectionsList列表,并将其传递给数据网格所在的用户控件的构造函数。我可以看到DataContext确实正在设置并显示列表中的项目,但是当我返回应用程序并尝试查看数据网格时,它是空白的

任何帮助都将不胜感激。在过去的一天半里,我一直在努力解决这个问题。谢谢

更新

SelectionList的设置如下:

public class SelectionList : List<Selection>
{
    public List<Selection> availableSelections = new List<Selection>();

    public List<Selection> AvailableSelections
    {
        get { return availableSelections; }
    }
}
当应用程序启动时,我构建一个现有产品(选择)的目录。在不同的选项卡上(每个产品系列对应一个选项卡),产品列表框的datacontext使用从目录中获取的可用产品进行初始化。然后,在用户选择哪个产品之前,与该产品相关的可用选项或子选项将填充到相应的列表框、附件和保修中

一旦用户选择了他们想要的选项,就会单击一个按钮来预览所选项目,这些项目将填充上述数据网格

我可以构建所选选项的列表,但是当我尝试设置数据网格的数据上下文时,什么也没有出现。可用选择的列表被构建并设置为适当的数据上下文,与我尝试为数据网格执行此操作的方式相同,但是数据网格不希望显示我的信息

更新

因此,在进行了更多的调试之后,我将问题缩小了一点。数据绑定可以正常工作。我想我在那里没有什么真正的问题。然而,我现在遇到的问题是,我认为我的用户控件有两个不同的实例,但只显示原始的,而不是更新的副本

这是一个来自about的类的副本,我添加了几行代码来帮助调试这个问题

public partial class QuotePreview : UserControl
{
    private SelectionList _selectionList;
    private SelectionList temp;

    public QuotePreview()
    {
        InitializeComponent();
        _selectionList = (SelectionList)this.DataContext;
    }

    private void QuotePreview_Loaded(object sender, RoutedEventArgs e)
    {
        _selectionList.SelectedOptions.Add(
            new Selection
            {
                ModelNumber = "this",
                Description = "really",
                Price = "sucks"
            });
    }

    public QuotePreview(SelectionList selectedOptions)
    {
        InitializeComponent();
        _selectionList = (SelectionList)this.DataContext;

        temp = selectedOptions;

        _selectionList.AddRange(selectedOptions);

        QuotePreview_Loaded();
    }

    private void QuotePreview_Loaded()
    {
        foreach (var options in temp.SelectedOptions)
        {
            _selectionList.SelectedOptions.Add(options);
        }

        QuotePreviewDataGrid.ItemsSource = _selectionList.SelectedOptions;
    }
}
public static class QuotePreview
{
    public static ObservableCollection<PurchasableItem> LineItems { get; private set; }

    static QuotePreview()
    {
        LineItems = new ObservableCollection<PurchasableItem>();
    }

    public static void Add(List<PurchasableItems> selections)
    {
        foreach (var selection in selections)
        {
            LineItems.Add(selection);
        }
    }

    public static void Clear()
    {
        LineItems.Clear();
    }
}

public class QuoteTab : TabItem
{
    public ObservableCollection<PurchasableItem> PreviewItems { get; private set; }

    public QuoteTab()
    {          
        Initialize()

        PreviewItems = QuotePreview.LineItems;

        DataGrid.ItemSource = PreviewItems
    }
}
每次单击用户控件/选项卡时,都会调用默认构造函数的实现。当发生这种情况时,_selectionList被设置为用户控件的数据上下文,然后是加载的事件,该事件向我的数据网格中添加一行

在另一个用户控件中,我选择要添加到数据网格用户控件中的选项,单击一个按钮,创建要添加的选项列表,并调用我编写的自定义构造函数。一旦构造函数完成,它将调用我为shits和giggles创建的自定义加载事件方法,该方法将所选选项添加到我的_selectionList中

现在,当我再次单击DataGrid用户控件时,它将完成整个默认过程,并添加另一个默认行

如果我返回一个选项卡并说我需要这些选项,然后返回到数据网格,它将再次执行默认过程并添加另一个默认行

但最有趣的是,我可以看到两个SelectionList都在构建,因为我没有清除中间的进程。我看到我要显示的选项的列表生成和默认选项生成的列表生成

哦,另外,SelectionList确实实现了ObservableCollection。

尝试更改:

QuotePreviewDataGrid.DataContext = previewList;

我怀疑xaml中的
ItemsSource=“{Binding}”
正在覆盖构造函数中的DataContext代码

通过将previewList更改为整个UserControl的DataContext,DataGrid的
项资源的绑定可以正确计算

另一方面,我将开始研究
observetecollection
和MVVM设计模式的使用。您可能最终遇到的一个问题是,当基础列表发生更改时,
DataGrid
不会更新,使用
observetecollection
将解决此问题


使用MVVM设计模式可以很好地将逻辑和数据(在本例中是列表及其加载方式)与物理显示(数据网格)分离开来。

我终于找到了解决问题的方法

public partial class QuotePreview : UserControl
{
    private SelectionList _selectionList;
    private SelectionList temp;

    public QuotePreview()
    {
        InitializeComponent();
        _selectionList = (SelectionList)this.DataContext;
    }

    private void QuotePreview_Loaded(object sender, RoutedEventArgs e)
    {
        _selectionList.SelectedOptions.Add(
            new Selection
            {
                ModelNumber = "this",
                Description = "really",
                Price = "sucks"
            });
    }

    public QuotePreview(SelectionList selectedOptions)
    {
        InitializeComponent();
        _selectionList = (SelectionList)this.DataContext;

        temp = selectedOptions;

        _selectionList.AddRange(selectedOptions);

        QuotePreview_Loaded();
    }

    private void QuotePreview_Loaded()
    {
        foreach (var options in temp.SelectedOptions)
        {
            _selectionList.SelectedOptions.Add(options);
        }

        QuotePreviewDataGrid.ItemsSource = _selectionList.SelectedOptions;
    }
}
public static class QuotePreview
{
    public static ObservableCollection<PurchasableItem> LineItems { get; private set; }

    static QuotePreview()
    {
        LineItems = new ObservableCollection<PurchasableItem>();
    }

    public static void Add(List<PurchasableItems> selections)
    {
        foreach (var selection in selections)
        {
            LineItems.Add(selection);
        }
    }

    public static void Clear()
    {
        LineItems.Clear();
    }
}

public class QuoteTab : TabItem
{
    public ObservableCollection<PurchasableItem> PreviewItems { get; private set; }

    public QuoteTab()
    {          
        Initialize()

        PreviewItems = QuotePreview.LineItems;

        DataGrid.ItemSource = PreviewItems
    }
}
公共静态类QuotePreview
{
公共静态ObservableCollection行项目{get;private set;}
静态QuotePreview()
{
LineItems=新的ObservableCollection();
}
公共静态无效添加(列表选择)
{
foreach(选择中的变量选择)
{
LineItems.Add(选择);
}
}
公共静态无效清除()
{
LineItems.Clear();
}
}
公共类QuoteTab:TabItem
{
公共可观测集合预览{get;private set;}
公共报价表
{          
初始化()
PreviewItems=QuotePreview.LineItems;
DataGrid.ItemSource=PreviewItems
}
}

好的,所以我尝试了您建议的更改,但没有效果。实际上,我已经准备好设置这个了;排除这种可能性。我也改变了,预览列表是一个可观察的集合,我的数据仍然没有显示。我们可以看到
选择列表
中项目的定义吗
public static class QuotePreview
{
    public static ObservableCollection<PurchasableItem> LineItems { get; private set; }

    static QuotePreview()
    {
        LineItems = new ObservableCollection<PurchasableItem>();
    }

    public static void Add(List<PurchasableItems> selections)
    {
        foreach (var selection in selections)
        {
            LineItems.Add(selection);
        }
    }

    public static void Clear()
    {
        LineItems.Clear();
    }
}

public class QuoteTab : TabItem
{
    public ObservableCollection<PurchasableItem> PreviewItems { get; private set; }

    public QuoteTab()
    {          
        Initialize()

        PreviewItems = QuotePreview.LineItems;

        DataGrid.ItemSource = PreviewItems
    }
}