在初次使用 Silverlight 2 Datagrid 元件後,覺得還可以。但在 databind 時,就無法像 asp.net 的 GridView 可以直接 format 資料格式了。
因此,我偷偷用了 anonymous type,做為資料轉格式的方式。
但失敗了。
寫了一個測試的 sample 如下。
Page.xaml
<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="SilverlightApplication2.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<data:DataGrid x:Name="dgNames" AutoGenerateColumns="True" Loaded="dgNames_Loaded"></data:DataGrid>
</Grid>
</UserControl>
Page.xaml.cs
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace SilverlightApplication2
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
}
private void dgNames_Loaded(object sender, RoutedEventArgs e)
{
List<string> myNames = new List<string> { "Charles", "Julia", "TingYu" };
var q = from n in myNames
select new
{
n
};
dgNames.ItemsSource = q.ToList();
}
}
}
結果出現錯誤
Webpage error details
User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.21022; .NET CLR 1.1.4322; .NET CLR 3.5.30729; .NET CLR 3.0.30618; MS-RTC LM 8; OfficeLiveConnector.1.3; OfficeLivePatch.0.0)
Timestamp: Thu, 14 May 2009 09:01:40 UTC
Message: Sys.InvalidOperationException: ManagedRuntimeError error #4004 in control 'Xaml1': System.MethodAccessException: <>f__AnonymousType0`1.get_n()
at System.Reflection.MethodBase.PerformSecurityCheck(Object obj, RuntimeMethodHandle method, IntPtr parent, UInt32 invocationFlags)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at System.Windows.Data.BindingExpression.ConnectToSource(Int32 index)
at System.Windows.Data.BindingExpression.DataContextChanged(Object o, DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.OnDataContextChanged(DataContextChangedEventArgs e)
at System.Windows.FrameworkElement.OnTreeParentUpdated(DependencyObject newParent, Boolean bIsNewParentAlive)
at System.Windows.DependencyObject.UpdateTreeParent(IManagedPeer newParent, Boolean bIsNewParentAlive)
at MS.Internal.FrameworkCallbacks.PeerTreeUpdate(IntPtr parentElement, IntPtr childElement, Byte bIsParentAlive)
Line: 453
Char: 17
Code: 0
URI: http://localhost:21320/ScriptResource.axd?d=v7RAdeBdTb1UtK_ZSZJcchuxmNZp7aBSXoH0iSyCwic_hoCgZtj9xlxZTDuqBow-wrdCLEr4fnN6W6pMvdTnOQ2&t=ffffffffafbd6209
天啊!無法不利的 LINQ 竟然在 Silverlight 2.0 敗下陣來。
看來是 Anonymous type 不太行了。因此改成下方的程式即可。斜粗體字的部份即是修改的部份。注意到 TempData 必須是 public。
Page.xaml.cs (Updated)
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace SilverlightApplication2
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
}
private void dgNames_Loaded(object sender, RoutedEventArgs e)
{
List<string> myNames = new List<string> { "Charles", "Julia", "TingYu" };
var q = from n in myNames
select new TempData
{
Name = n
};
dgNames.ItemsSource = q.ToList();
}
public class TempData
{
public string Name { get; set; }
}
}
}
這樣就正常了。