2009年5月14日 星期四

Silverlight 2: Datagrid 無法 Binding Anonymous type

在初次使用 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; }
    }
  }
}
這樣就正常了。
image 

沒有留言:

Share with Facebook