WPF DataBinding ObservableCollection<T> to DataGrid

本文关键字:gt to DataGrid lt DataBinding ObservableCollection WPF | 更新日期: 2023-09-27 18:01:23

我试图在一个单独的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.ItemsSource = PreviewList;

我还尝试设置数据上下文和itemsource以及刷新:

QuotePreviewDataGrid.Items.Refresh();

在应用程序的其余部分中,我为列表框设置的数据绑定工作得很好。在列表框中,我将itemsource设置为{Binding},将listtiitems绑定设置为{Binding Property}。后面代码中设置的列表框的数据上下文。

我这里的数据网格是以相同的方式设置的,但由于某种原因,网格内没有显示任何内容。

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

任何帮助都将非常感激。在过去的一天半里,我一直在思考这个问题。谢谢!

选择列表设置如下:

public class SelectionList : List<Selection>
{
    public List<Selection> availableSelections = new List<Selection>();
    public List<Selection> AvailableSelections
    {
        get { return availableSelections; }
    }
}

和一个选择,然后定义为:

public class Selection : DependencyObject
{
    public bool IsChecked { get; set; }
    public string ModelNumber { get; set; }
    public string Description { get; set; }
    public string Price { get; set; }
}

当应用程序启动时,我构建一个现有产品的目录(选择)。在不同的选项卡上,每个产品族对应一个选项卡,产品列表框的数据上下文初始化为从目录中获取的可用产品。然后,在用户选择哪个产品之前,与该产品相关的可用选项或子选择将填充到相应的列表框、附件和保修中。

一旦用户选择了他们想要的选项,就会点击一个按钮来预览选中的项目,这些项目应该填充上面解释的数据网格。

我可以构建所选选项的列表,但是当我试图设置数据网格的数据上下文时,什么也没有出现。可用选择的列表被构建并设置为适当的数据上下文,就像我试图为数据网格做的那样,但是数据网格不想显示我的信息。

因此,经过更多的调试,我已经缩小了问题的范围。数据绑定正常工作。我想我在那里没有真正的问题。然而,我现在遇到的问题是我认为是我的用户控制的2个不同的实例,但只有原来的被显示,而不是更新的副本。

下面是这个类的副本,我添加了几行来帮助调试这个问题。

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;
    }
}

默认构造函数的实现,在每次单击用户控件/选项卡时调用。当发生这种情况时,_selectionList被设置为用户控件的数据上下文,然后是Loaded Event,它向我的数据网格添加一行。

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

现在,一旦我再次单击数据网格用户控件,它将执行整个默认过程,并添加另一个默认行。

如果我回到一个选项卡,说我想要这些选项,回到数据网格,它再次通过默认过程,并添加另一个默认行。

最有趣的是,我可以看到两个selectionLists构建,因为我没有清除进程之间。我看到了我想要显示的选项的列表构建和默认选项的列表构建…

哦,还有,SelectionList确实实现了ObservableCollection。

WPF DataBinding ObservableCollection<T> to DataGrid

我终于想出了一个解决问题的办法。
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
    }
}

尝试更改:

QuotePreviewDataGrid.DataContext = previewList;

this.DataContext = previewList;

我怀疑你的xaml中的ItemsSource="{Binding}"覆盖了构造函数中的DataContext代码。

通过将previewList更改为整个UserControl的DataContext,那么DataGrid的ItemsSource的绑定可以正确计算。

在旁注中,我将开始研究ObservableCollection<T>和MVVM设计模式的使用。您可能最终遇到的一个问题是,当底层列表更改时,您的DataGrid不会更新,使用ObservableCollection<T>将解决此问题。

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