绑定到EF实体时向WPF DataGrid添加行(以编程方式执行“UserCanAddRows”)

时间:2013-01-22 09:08:47

标签: wpf entity-framework binding datagrid wpfdatagrid

DataGrid有一个名为“UserCanAddRows”的功能,它为用户提供了一个空行,可用于向DataGrid添加新行。但是,我想为我的用户提供一个额外的控件来添加新行,如下面的屏幕截图所示。

enter image description here

但现在问题出现了。我将DataGrid绑定到Microsoft Entity Framework的ObjectSet。将项添加到ObjectSet时,除非我将更改保存到数据库,否则它不会出现在那里。因此,addedObject被保存到一些额外的列表中,该列表包含所有“挂起的更改”。但是,当我以编程方式添加它时,我的DataGrid不知道这个“挂起的更改或ObjectStateList”。因此,它们不会显示在DataGrid中,也不会在刷新视图后显示。

但是,当使用“UserCanAddRows”-Feature时,DataGrid会发现它们!因此,我想要做的就是以编程方式使用此功能或模仿功能所做的事情。

现在,我的相关代码:

        private readonly MyEntities m_db;
        private CollectionViewSource m_workItemViewSource;
        private ObjectSet<WorkItem> m_workItems;

        public SettingsWindow(MyEntities db)
        {
            m_db = db;
            InitializeComponent(); 
            m_workItemViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("workItemViewSource")));

        }


        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            m_workItems = m_db.WorkItems;
            m_workItemViewSource.Source = m_workItems;
        }

       private void AddWorkItemButton_Click(object sender, RoutedEventArgs e)
        {
            WorkItem workItem = m_db.CreateObject<WorkItem>();
            workItem.name = AddWorkItemTextBox.Text;
            workItem.is_shown = true;
            AddWorkItemTextBox.Text = "";
            m_workItems.AddObject(workItem);
            m_workItemViewSource.View.Refresh();
        }

这里是XAML

  <Window.Resources>
        <CollectionViewSource x:Key="workItemViewSource" d:DesignSource="{d:DesignInstance my:WorkItem, CreateList=True}" />
    </Window.Resources>

   <DockPanel Name="WindowDockPanel"  LastChildFill="True" DataContext="{StaticResource workItemViewSource}">

    <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True"  ItemsSource="{Binding}" Name="workItemDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Width="280" CanUserAddRows="True" CanUserDeleteRows="False">
     <DataGrid.Columns>
      <DataGridCheckBoxColumn x:Name="is_shownColumn" Binding="{Binding Path=is_shown, Mode=TwoWay}" Header="{x:Static Resources:EntityStrings.isShown}" Width="SizeToHeader" >
      </DataGridCheckBoxColumn>
      <DataGridTextColumn x:Name="nameColumn" Binding="{Binding Path=name, Mode=TwoWay}" Header="{x:Static Resources:EntityStrings.workItem}" Width="*" />
     </DataGrid.Columns>  
    </DataGrid>  

  </DockPanel>

1 个答案:

答案 0 :(得分:0)

我已经继续前进并以不同的方式实施它。但我现在获得了一些经验。我学到的是,EF上下文的集合(在我的例子中是m_db)没有实现INotifyChange接口。他们也没有在列表中添加新添加的条目。我在另一个地方再次遇到这个问题并且这次“正确”修复了这个问题:

关键是不要使用上下文给出的集合。如果你将它们放在像ObservableCollection这样的不同集合中,它并没有坏处。所以它应该适用于这种变化,但我不能再测试它了:

    private readonly MyEntities m_db;
    private CollectionViewSource m_workItemViewSource;
    private ObserverableCollection<WorkItem> m_workItems; //changed!
    public SettingsWindow(MyEntities db)
    {
        m_db = db;
        InitializeComponent(); 
        m_workItemViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("workItemViewSource")));

    }


    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        m_workItems = new ObservableCollection( m_db.WorkItems ); //changed!
        m_workItemViewSource.Source = m_workItems;
    }

   private void AddWorkItemButton_Click(object sender, RoutedEventArgs e)
    {
        WorkItem workItem = m_db.CreateObject<WorkItem>();
        workItem.name = AddWorkItemTextBox.Text;
        workItem.is_shown = true;
        AddWorkItemTextBox.Text = "";
        m_workItems.AddObject(workItem);
        m_workItemViewSource.View.Refresh();
    }