0

DataGrid には、DataGrid に新しい行を追加するために使用できる空の行をユーザーに提供する「UserCanAddRows」と呼ばれる機能があります。ただし、下のスクリーンショットに示すように、新しい行を追加するための特別なコントロールをユーザーに提供したいと考えています。

ここに画像の説明を入力

しかし今、問題が提起されています。私は DataGrid を Microsoft Entity Framework の ObjectSet にバインドしています。ObjectSet にアイテムを追加するとき、変更をデータベースに保存しない限り、アイテムはそこに表示されません。したがって、 addedObject は、すべての「保留中の変更」を保持する追加のリストに保存されます。ただし、プログラムで追加すると、DataGrid はこの「保留中の変更または ObjectStateList」を認識しません。そのため、ビューを更新した後でも、DataGrid には表示されません。

しかし、「UserCanAddRows」機能が使用されている場合、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>
4

1 に答える 1

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();
    }
于 2013-02-01T15:24:18.577 に答える