簡體   English   中英

創建可編輯的DataGrid時出錯

[英]Error while creating an editable DataGrid

我已經設法擺脫了LINQ的困擾。 我正在嘗試使用從LINQ查詢收集的子集在WPF應用程序中創建可編輯的數據網格:

var LookUpEvents = from d in ThisData.Events.Local
                   where d.StartDate.Value.Date <= DateTime.Now.Date &&
                   (d.EndDate.HasValue == false || d.EndDate.Value.Date >= DateTime.Now.Date)
                   select d;
RangeEventGrid.ItemsSource = LookUpEvents;
RangeEventGrid.Items.Refresh();

嘗試拋出此異常時,此查詢有效,並且已填充數據網格,但是我無法編輯數據網格:

"'EditItem' is not allowed for this view."
   at System.Windows.Controls.ItemCollection.System.ComponentModel.IEditableCollectionView.EditItem(Object item)
   at System.Windows.Controls.DataGrid.EditRowItem(Object rowItem)

使用以下方法加載完整的數據集時:

ThisData.Events.Load();
FullEventGrid.ItemsSource = ThisData.Events.Local;

一切正常,數據可編輯。 所使用的XAML是相同的(我也嘗試過交換綁定的數據網格,並且完整結果仍可編輯,並且查詢仍然引發異常),而兩者之間的唯一區別是查詢。 當我嘗試更改查詢時,我遇到了一個新的異常:

The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

用於該查詢:

var LookUpEvents = from d in ThisData.Events
                   where d.StartDate.Value.Date <= DateTime.Now.Date &&
                   (d.EndDate.HasValue == false || d.EndDate.Value.Date >= DateTime.Now.Date)
                   select d;
LookUpEvents.Load(); //Exception thrown here.
RangeEventGrid.ItemsSource = LookUpEvents;
RangeEventGrid.Items.Refresh();

關於該異常的真正奇怪之處(至少對我來說是奇怪的)是,我在不引發任何異常的其他查詢中使用了DateTime比較,例如,該查詢在另一個地方運行良好:

var LookUpSessions = from d in ThisData.Sessions
                     where d.EndTime.Hour >= (DateTime.Now.Hour - 1) && d.StartTime.Hour <= (DateTime.Now.Hour + 2)
                     && d.Event.IsActive == true
                     orderby d.StartTime.Hour, d.StartTime.Minute
                     select d;

是否可以將LINQ查詢結果綁定到DataGrid以使其可編輯? 如果真是這樣,這似乎將是一個巨大的疏忽。 我覺得我很可能會錯過一些基本的東西,因為LINQ,WPF和EF對我來說都是全新的。

提前致謝。

為了使在GridView中編輯數據成為可能, 您不能使用IEnumerable<T>IQueryable<T>作為項目源。 您需要一個實現IList的集合類型,而IEnumerable<T>IQueryable<T>則不需要。

一個可能的解決方案是從LINQ查詢中創建一個ObservableCollection<T> (它確實實現了IList ):

RangeEventGrid.ItemsSource = new ObservableCollection<Event>(LookUpEvents);

這也是為什么

FullEventGrid.ItemsSource = ThisData.Events.Local;

工作,因為Local已經是類型ObservableCollection<Event>

您的第一個查詢不會引發異常(盡管您使用的是DateTime.Date ),因為它不是LINQ到實體/數據庫查詢。 這是在Local集合的內存中運行的LINQ到對象查詢。 沒有涉及數據庫查詢。

如果刪除Local ,則運行LINQ-to-Entities,並且LINQ-to-Entities不支持LINQ-to-Objects所支持的所有方法和屬性,尤其是它不支持DateTime.Date (但顯然支持DateTime.Hour )。

要在LINQ-to-Entities查詢中按Date執行比較,可以使用EntityFunctions

var today = DateTime.Now.Date;
var LookUpEvents = from d in ThisData.Events
                   where EntityFunction.TruncateTime(d.StartDate) <= today &&
                         (!d.EndDate.HasValue ||
                          EntityFunction.TruncateTime(d.EndDate) >= today)
                   select d;

也許也可以選擇EntityFunction.DiffDays函數。

問題解決了!

在綁定中添加了.ToList() ,它可以工作!

完整的LINQ查詢:

var LookUpEvents = from d in ThisData.Events.Local
                   where d.StartDate.Value.Date <= DateTime.Now.Date &&
                   (d.EndDate.HasValue == false || d.EndDate.Value.Date >= DateTime.Now.Date)
                   select d;

// Old binding: RangeEventGrid.ItemsSource = LookUpEvents;
// New binding:
RangeEventGrid.ItemsSource = LookUpEvents.ToList(); // .ToList() Fixes it!
RangeEventGrid.Items.Refresh();

http://xkcd.com/979/為名的自我解答

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM