Syncfusion sfDatagrid 的 Catel UIVisualizerService 问题
Catel UIVisualizerService issue with Syncfusion sfDatagrid
我创建了一个使用 Catel、Entity Framework6 和 Syncfusion Community Edition 的项目。具体来说,我使用的是 Syncfusion 的 sfDataGrid。
我遇到了一个让我完全难过的问题,也许有人能给我指出正确的方向。
我有一个带有 sfDataGrid 的 Catel UserControl。 ViewModel 具有我用作 sfDataGrid 的 ItemsSource 的数据的 ObservableCollection (Catel 属性)。我在 sfDataGrid 上启用了过滤。这是 sfDataGrid 的代码:
<sync:SfDataGrid
x:Name="ItemsDataGrid"
ItemsSource="{Binding MyItems, Mode=OneWay}"
SelectedItem="{Binding MyItem, Mode=TwoWay}"
AutoGenerateColumns="False"
AllowFiltering="True"
AllowResizingColumns="True"
GridCopyOption="IncludeHeaders"
GridPasteOption="None"
ShowGroupDropArea="True"
ShowRowHeader="True"
DataFetchSize="50">
<!-- Columns -->
</sync:SfDataGrid>
我在不同的视图中向 collection 添加了一个新项目,然后将其保存到数据上下文并刷新列表:
private async void OnNewMyItemExecute()
{
MyItem= new MyItem();
MyItemsRepository.Add(MyItem);
var myItemsViewModel = TypeFactory
.Default
.CreateInstanceWithParametersAndAutoCompletion<myItemsViewModel >(MyItem); //the construction has parameters for IUIVisualizerService, IPleaseWaitService, etc.
if (await _UIVisualizerService.ShowDialogAsync(myItemsViewModel) ?? true)
{
var myItem= myItemsViewModel.MyItem;
await InitializeAsync();
MyItem = myItem;
}
else
{
_UnitOfWorkService.Rollback(); //just undo some changes
MyItem = null;
}
UnitOfWork.SaveChanges();
}
创建一个新项目根本不是问题,奇怪的是,在我创建一个新项目之后,然后尝试在 sfDataGrid 的任何列上筛选网格(单击列中的筛选按钮 header,将打开一个过滤器弹出窗口,在条件文本框中输入一个值并单击 'OK'),我明白了:
MyProject.vshost.exe Warning: 0 : 17:57:49:075 => [WARNING]
[Catel.Services.UIVisualizerService] [8] An error occurred, returning
null since we don't know the result | [TargetInvocationException]
System.Reflection.TargetInvocationException: Exception has been thrown
by the target of an invocation. --->
System.Reflection.TargetInvocationException: Exception has been thrown
by the target of an invocation. ---> System.InvalidCastException:
Unable to cast object of type 'MyProject.Domain.MyItem' to type
'System.Data.Entity.DynamicProxies.MyItem_4CA6F59AB53174892ED9EFBC1D3CC07B862579FC3C5733C6CF4DE857907CFF9C'.
at lambda_method(Closure , MyItem ) --- End of inner exception
stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object
target, Object[] arguments, Signature sig, Boolean constructor) at
System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj,
Object[] parameters, Object[] arguments) at
System.Delegate.DynamicInvokeImpl(Object[] args) at
System.Delegate.DynamicInvoke(Object[] args) at
Syncfusion.Data.QueryableCollectionView.<>c__DisplayClass3.b__1(Object
o) at Syncfusion.Data.QueryableCollectionView.FilterRecord(Object
record) at
Syncfusion.Data.EnumerableRecordsWrapper..ctor(IEnumerable source,
CollectionViewAdv view) at
Syncfusion.Data.EnumerableRecordsWrapper.CreateNew(IEnumerable source,
CollectionViewAdv view) at
Syncfusion.Data.QueryableCollectionView.CreateRecords() at
Syncfusion.Data.CollectionViewAdv.EnsureInitialized() at
Syncfusion.Data.CollectionViewAdv.get_Records() at
Syncfusion.Data.CollectionViewAdv.EnsureRecordsInitialized() at
Syncfusion.Data.CollectionViewAdv.Refresh() at
Syncfusion.Data.QueryableCollectionView.RefreshFilter() at
Syncfusion.Data.CollectionViewAdv.ApplyFilters() at
Syncfusion.Data.CollectionViewAdv.set_FilterPredicates(ObservableCollection1
value) at Syncfusion.UI.Xaml.Grid.GridModel.FilterColumn(GridColumn
column, List
1 filterPredicates) at
Syncfusion.UI.Xaml.Grid.GridFilterControl.RefreshFilter() at
Syncfusion.UI.Xaml.Grid.GridFilterControl.b__10(Object
s, RunWorkerCompletedEventArgs e) at
System.ComponentModel.BackgroundWorker.OnRunWorkerCompleted(RunWorkerCompletedEventArgs
e) at
System.ComponentModel.BackgroundWorker.AsyncOperationCompleted(Object
arg) at
System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate
callback, Object args, Int32 numArgs) at
System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source,
Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl() at
System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object
state) at
System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state) at
System.Windows.Threading.DispatcherOperation.Invoke() at
System.Windows.Threading.Dispatcher.ProcessQueue() at
System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32
msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at
MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam,
IntPtr lParam, Boolean& handled) at
MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at
System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate
callback, Object args, Int32 numArgs) at
System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source,
Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at
System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority
priority, TimeSpan timeout, Delegate method, Object args, Int32
numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd,
Int32 msg, IntPtr wParam, IntPtr lParam) at
MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at
System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame
frame) at
System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Window.ShowHelper(Object booleanBox) at
System.Windows.Window.Show() at System.Windows.Window.ShowDialog()
--- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[]
arguments, Signature sig, Boolean constructor) at
System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj,
Object[] parameters, Object[] arguments) at
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[]
parameters) at
Catel.Services.UIVisualizerService.<>c__DisplayClass23_0.b__0()
in
C:\CI_WS\Ws058\Source\Catel\src\Catel.MVVM\Catel.MVVM.Shared\Services\UIVisualizerService.cs:line
499
这是 UIVisualizerService 的方法,第 499 行:
protected virtual bool? ShowWindow(FrameworkElement window, bool showModal)
{
if (showModal)
{
var showDialogMethodInfo = window.GetType().GetMethodEx("ShowDialog");
if (showDialogMethodInfo != null)
{
// Child window does not have a ShowDialog, so not null is allowed
bool? result = null;
window.Dispatcher.InvokeIfRequired(() =>
{
// Safety net to prevent crashes when this is the main window
try
{
result = showDialogMethodInfo.Invoke(window, null) as bool?; //Line 499
}
catch (Exception ex)
{
Log.Warning(ex, "An error occurred, returning null since we don't know the result");
}
});
return result;
}
Log.Warning("Method 'ShowDialog' not found on '{0}', falling back to 'Show'", window.GetType().Name);
}
我曾尝试使用 .ShowAsync()、.ShowDialogAsync() 打开 MyItemsView,在升级到 Catel 4.4 之前我还使用了 .ShowDialog(),但没有任何区别。我可以在 EF 中关闭代理创建,但这会导致我必须在我的项目中进行大量更改(对我来说不再需要延迟加载,这不是一个选项)。我相信问题是我添加的新项目不是动态代理,让它成为动态代理可能会解决这个问题,但我已经尝试再次从 DbContext 加载所有数据,但它也没有解决问题。
如有任何建议,我们将不胜感激。
问题是这样的:
System.InvalidCastException: Unable to cast object of type 'MyProject.Domain.MyItem' to type 'System.Data.Entity.DynamicProxies.MyItem_4CA6F59AB53174892ED9EFBC1D3CC07B862579FC3C5733C6CF4DE857907CFF9C'.
当然,原因是您试图将基类型转换为派生类型(事实并非如此)。这最终导致 window 关闭是因为发生了异常,但这不是真正的问题。
此异常发生在网格的FilterRecord 方法中。我不确定那是你自己写的还是 syncfusion 里面的东西,但这是值得一看的地方。
您生成代理的原因是您启用(或默认启用)Entity Framework DbContext 的代理生成。
我创建了一个使用 Catel、Entity Framework6 和 Syncfusion Community Edition 的项目。具体来说,我使用的是 Syncfusion 的 sfDataGrid。
我遇到了一个让我完全难过的问题,也许有人能给我指出正确的方向。
我有一个带有 sfDataGrid 的 Catel UserControl。 ViewModel 具有我用作 sfDataGrid 的 ItemsSource 的数据的 ObservableCollection (Catel 属性)。我在 sfDataGrid 上启用了过滤。这是 sfDataGrid 的代码:
<sync:SfDataGrid
x:Name="ItemsDataGrid"
ItemsSource="{Binding MyItems, Mode=OneWay}"
SelectedItem="{Binding MyItem, Mode=TwoWay}"
AutoGenerateColumns="False"
AllowFiltering="True"
AllowResizingColumns="True"
GridCopyOption="IncludeHeaders"
GridPasteOption="None"
ShowGroupDropArea="True"
ShowRowHeader="True"
DataFetchSize="50">
<!-- Columns -->
</sync:SfDataGrid>
我在不同的视图中向 collection 添加了一个新项目,然后将其保存到数据上下文并刷新列表:
private async void OnNewMyItemExecute()
{
MyItem= new MyItem();
MyItemsRepository.Add(MyItem);
var myItemsViewModel = TypeFactory
.Default
.CreateInstanceWithParametersAndAutoCompletion<myItemsViewModel >(MyItem); //the construction has parameters for IUIVisualizerService, IPleaseWaitService, etc.
if (await _UIVisualizerService.ShowDialogAsync(myItemsViewModel) ?? true)
{
var myItem= myItemsViewModel.MyItem;
await InitializeAsync();
MyItem = myItem;
}
else
{
_UnitOfWorkService.Rollback(); //just undo some changes
MyItem = null;
}
UnitOfWork.SaveChanges();
}
创建一个新项目根本不是问题,奇怪的是,在我创建一个新项目之后,然后尝试在 sfDataGrid 的任何列上筛选网格(单击列中的筛选按钮 header,将打开一个过滤器弹出窗口,在条件文本框中输入一个值并单击 'OK'),我明白了:
MyProject.vshost.exe Warning: 0 : 17:57:49:075 => [WARNING] [Catel.Services.UIVisualizerService] [8] An error occurred, returning null since we don't know the result | [TargetInvocationException] System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidCastException: Unable to cast object of type 'MyProject.Domain.MyItem' to type 'System.Data.Entity.DynamicProxies.MyItem_4CA6F59AB53174892ED9EFBC1D3CC07B862579FC3C5733C6CF4DE857907CFF9C'. at lambda_method(Closure , MyItem ) --- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Delegate.DynamicInvokeImpl(Object[] args) at System.Delegate.DynamicInvoke(Object[] args) at Syncfusion.Data.QueryableCollectionView.<>c__DisplayClass3.b__1(Object o) at Syncfusion.Data.QueryableCollectionView.FilterRecord(Object record) at Syncfusion.Data.EnumerableRecordsWrapper..ctor(IEnumerable source, CollectionViewAdv view) at Syncfusion.Data.EnumerableRecordsWrapper.CreateNew(IEnumerable source, CollectionViewAdv view) at Syncfusion.Data.QueryableCollectionView.CreateRecords() at Syncfusion.Data.CollectionViewAdv.EnsureInitialized() at Syncfusion.Data.CollectionViewAdv.get_Records() at Syncfusion.Data.CollectionViewAdv.EnsureRecordsInitialized() at Syncfusion.Data.CollectionViewAdv.Refresh() at Syncfusion.Data.QueryableCollectionView.RefreshFilter() at Syncfusion.Data.CollectionViewAdv.ApplyFilters() at Syncfusion.Data.CollectionViewAdv.set_FilterPredicates(ObservableCollection
1 value) at Syncfusion.UI.Xaml.Grid.GridModel.FilterColumn(GridColumn column, List
1 filterPredicates) at Syncfusion.UI.Xaml.Grid.GridFilterControl.RefreshFilter() at Syncfusion.UI.Xaml.Grid.GridFilterControl.b__10(Object s, RunWorkerCompletedEventArgs e) at System.ComponentModel.BackgroundWorker.OnRunWorkerCompleted(RunWorkerCompletedEventArgs e) at System.ComponentModel.BackgroundWorker.AsyncOperationCompleted(Object arg) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Windows.Threading.DispatcherOperation.Invoke() at System.Windows.Threading.Dispatcher.ProcessQueue() at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Window.ShowHelper(Object booleanBox) at System.Windows.Window.Show() at System.Windows.Window.ShowDialog() --- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) at Catel.Services.UIVisualizerService.<>c__DisplayClass23_0.b__0() in C:\CI_WS\Ws058\Source\Catel\src\Catel.MVVM\Catel.MVVM.Shared\Services\UIVisualizerService.cs:line 499
这是 UIVisualizerService 的方法,第 499 行:
protected virtual bool? ShowWindow(FrameworkElement window, bool showModal)
{
if (showModal)
{
var showDialogMethodInfo = window.GetType().GetMethodEx("ShowDialog");
if (showDialogMethodInfo != null)
{
// Child window does not have a ShowDialog, so not null is allowed
bool? result = null;
window.Dispatcher.InvokeIfRequired(() =>
{
// Safety net to prevent crashes when this is the main window
try
{
result = showDialogMethodInfo.Invoke(window, null) as bool?; //Line 499
}
catch (Exception ex)
{
Log.Warning(ex, "An error occurred, returning null since we don't know the result");
}
});
return result;
}
Log.Warning("Method 'ShowDialog' not found on '{0}', falling back to 'Show'", window.GetType().Name);
}
我曾尝试使用 .ShowAsync()、.ShowDialogAsync() 打开 MyItemsView,在升级到 Catel 4.4 之前我还使用了 .ShowDialog(),但没有任何区别。我可以在 EF 中关闭代理创建,但这会导致我必须在我的项目中进行大量更改(对我来说不再需要延迟加载,这不是一个选项)。我相信问题是我添加的新项目不是动态代理,让它成为动态代理可能会解决这个问题,但我已经尝试再次从 DbContext 加载所有数据,但它也没有解决问题。
如有任何建议,我们将不胜感激。
问题是这样的:
System.InvalidCastException: Unable to cast object of type 'MyProject.Domain.MyItem' to type 'System.Data.Entity.DynamicProxies.MyItem_4CA6F59AB53174892ED9EFBC1D3CC07B862579FC3C5733C6CF4DE857907CFF9C'.
当然,原因是您试图将基类型转换为派生类型(事实并非如此)。这最终导致 window 关闭是因为发生了异常,但这不是真正的问题。
此异常发生在网格的FilterRecord 方法中。我不确定那是你自己写的还是 syncfusion 里面的东西,但这是值得一看的地方。
您生成代理的原因是您启用(或默认启用)Entity Framework DbContext 的代理生成。