我正在创建的WPF应用程序的窗口出现问题。尝试将ObservableCollection绑定到DataGrid时出现错误。让我感到困惑的是,Datagrid似乎正在使用其中已存在的值进行实例化,从而导致以下错误:
PresentationFramework.dll中发生了'System.InvalidOperationException'类型的未处理异常 使用ItemsSource之前,Items集合必须为空。
XAML代码:
<Window x:Class="Store_grade_list_bulk_updater.POModifyWindow"
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:Store_grade_list_bulk_updater"
mc:Ignorable="d"
Title="Modify Or Remove Grades & PO Numbers" Height="450" Width="850"
KeyDown="Escape_KeyDown">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
VerticalAlignment="Top"
HorizontalAlignment="Center"
Margin="0,30,0,0">
<TextBlock>
Grade Code:
</TextBlock>
<TextBox
x:Name="GradeBox"
KeyDown="Grade_KeyDown">
</TextBox>
<TextBlock
Margin="0,10,0,0">
Purchase Order Code:
</TextBlock>
<TextBox
x:Name="POBOx"
KeyDown="PO_KeyDown">
</TextBox>
<Button
Margin="0,20,0,0"
Content="Modify"
Click="Modify_Click"/>
<Button
Margin="0,15,0,0"
Content="Close Window"
Click="CloseWindow_Click"/>
</StackPanel>
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<DataGrid
Grid.Column="0"
x:Name="Modify_GradeList"
Margin="10"
AutoGenerateColumns="False"
ItemsSource="{Binding}"
IsReadOnly="True"
CanUserAddRows="False"
SelectionChanged="GradeList_Select">
<DataGridTextColumn Header="Grade Code" Binding="{Binding Path=Grade}"/>
</DataGrid>
<DataGrid
Grid.Column="1"
x:Name="Modify_PO_List"
Margin="10"
AutoGenerateColumns="False"
ItemsSource="{Binding}"
IsReadOnly="True"
SelectionChanged="PO_List_Select">
<DataGridTextColumn Header="PO Code" Binding="{Binding PO_Code}" Width="3*"/>
<DataGridTextColumn Header="Country" Binding="{Binding Country}" Width="*"/>
<DataGridTextColumn Header="Stores" Binding="{Binding Store_Count}" Width="*"/>
</DataGrid>
<DataGrid
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="1"
x:Name="Store_List"
Margin="10,0,10,10"
ItemsSource="{Binding}"
AutoGenerateColumns="False"
IsReadOnly="True">
<DataGridTextColumn Header="Code" Binding="{Binding Store_Code}" Width="*"/>
<DataGridTextColumn Header="Code" Binding="{Binding Store_Name}" Width="4*"/>
<DataGridTextColumn Header="Code" Binding="{Binding Grade_Rank}" Width="*"/>
</DataGrid>
</Grid>
</Grid>
C#代码:
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Store_grade_list_bulk_updater
{
public partial class POModifyWindow : Window
{
public ObservableCollection<GradeTemplate.Template> modify_grades = new ObservableCollection<GradeTemplate.Template>();
public ObservableCollection<GradeTemplate.PO> modify_po_list = new ObservableCollection<GradeTemplate.PO>();
public ObservableCollection<GradeTemplate.Grade> modify_grade_details = new ObservableCollection<GradeTemplate.Grade>();
public POModifyWindow()
{
InitializeComponent();
MainWindow tempMain = (MainWindow)Application.Current.MainWindow;
// This returns "1"
MessageBox.Show(Modify_GradeList.Items.Count.ToString());
// Troubleshooting step
Modify_GradeList.ItemsSource = modify_grades;
// End troubleshooting
modify_grades = tempMain.gradelist;
Modify_GradeList.ItemsSource = modify_grades;
Modify_PO_List.ItemsSource = modify_po_list;
Store_List.ItemsSource = modify_grade_details;
}
public void Modify_Click(object sender, EventArgs e)
{
}
public void CloseWindow_Click(object sender, EventArgs e)
{
MainWindow tempMain = (MainWindow)Application.Current.MainWindow;
tempMain.ReceiveTemplates(modify_grades);
Close();
}
public void GradeList_Select (object sender, EventArgs e)
{
modify_po_list = Modify_GradeList.SelectedItem as ObservableCollection<GradeTemplate.PO>;
Modify_PO_List.ItemsSource = modify_po_list;
GradeTemplate.Template textbox_temp = Modify_GradeList.SelectedItem as GradeTemplate.Template;
GradeBox.Text = textbox_temp.Grade;
}
public void PO_List_Select(object sender, EventArgs e)
{
}
public void Escape_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
MainWindow tempMain = (MainWindow)Application.Current.MainWindow;
tempMain.ReceiveTemplates(modify_grades);
Close();
}
}
public void Grade_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
TextBox s = e.Source as TextBox;
s.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
}
}
public void PO_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
GradeBox.Clear();
POBOx.Clear();
TextBox s = e.Source as TextBox;
s.MoveFocus(new TraversalRequest(FocusNavigationDirection.Up));
}
}
}
}
最初,我认为这是由于尝试将集合与其中已存在的对象绑定而造成的,尽管这已经在另一个窗口中起作用了,但是当我在标记为故障排除的代码行中添加代码时,仍然会导致错误。据我所知,它似乎与XAML某种程度上有关,因为该错误仅在我添加了文本列以尝试并具有一致的格式后才开始发生,但我无法确定它的发生位置或原因。
答案 0 :(得分:1)
如果要在DataGrid中创建列,则需要具有<DataGrid.Columns>
在内部,您需要定义列。
直接通过定义列来假设它具有数据,因此它认为您两次提供了itemSource
,因此出现了错误:-Collection must be empty before using
ItemsSource
<DataGrid
Grid.Column="0"
x:Name="Modify_GradeList"
Margin="10"
AutoGenerateColumns="False"
ItemsSource="{Binding}"
IsReadOnly="True"
CanUserAddRows="False"
SelectionChanged="GradeList_Select">
<DataGrid.Columns>
<DataGridTextColumn Header="Grade Code" Binding="{Binding Path=Grade}"/>
</DataGrid.Columns>
</DataGrid>
对其他DataGrid进行相同的操作。