WPF和WinRT之间的绑定行为与动态对象不同

时间:2014-05-26 19:04:54

标签: c# dynamic json.net winrt-xaml expandoobject

我正在尝试将Xaml属性数据绑定到动态对象的属性。在这种情况下,动态对象是Json.Net library中的JObjectJObject是一个表现良好的动态对象,过去我对它没有任何问题。它使得json序列化对象和C#代码的轻量级方式成为可能。

在这种情况下,绑定会在运行时抛出异常。

绑定:

 <TextBlock Text="{Binding UserProfile.Value.name}"/>

其中ValueJObjectname是动态属性(字符串)

例外:

    Error: BindingExpression path error: 'name' property not found on 'Newtonsoft.Json.Linq.JObject, 
Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. 
BindingExpression: Path='UserProfile.Value.name' DataItem='Google.Apps.ViewModel.MainViewModel'; 
target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' 
(type 'String')

奇怪的是,如果我将JObject显式转换为ExpandoObject,则绑定可以正常工作。

private dynamic _value; // set to a deserialized JObject elsewhere
public dynamic Value
{
    get
    {
        if (_value != null) // debug code
        {
            dynamic o = new ExpandoObject();
            o.name = _value.name;
            return o;
        }
        return _value;
    }
}

要绑定到动态对象,数据对象必须是ExpandoObject。显然,绑定是询问dataobject的类型并使用反射来获取属性和值。 ExpandoObject是否有特殊情况逻辑,而ExpandoObject是执行此操作的唯一选择吗?

更新

正如@dkozl指出这种类型的绑定可以直接使用WPF。我可以使用此WPF窗口和动态属性获得所需的行为:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="root"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel Orientation="Vertical">
            <TextBlock FontSize="36" Width="920">Label</TextBlock>
            <TextBlock Text="{Binding Path=TheName.name, ElementName=root}" FontSize="36"/>
        </StackPanel>
    </Grid>
</Window>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    public dynamic TheName
    {
        get
        {
            string json = @"{ 'name': 'James' }";
            return JsonConvert.DeserializeObject<dynamic>(json);
        }
    }
}

然而,对于WinRT 8.1 Store应用程序,这种非常相似的绑定会产生错误:

<Page
    x:Name="root"
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

  <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel Orientation="Vertical">
      <TextBlock FontSize="36" >Label</TextBlock>
      <TextBlock Text="{Binding Path=TheName.name, ElementName=root}" FontSize="36"/>
    </StackPanel>
  </Grid>
</Page>
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    public dynamic TheName
    {
        get
        {
            string json = @"{ 'name': 'James' }";
            return JsonConvert.DeserializeObject<dynamic>(json);
        }
    }
}

演示此内容的简单项目是here。不幸的是,它看起来像是WinRT绑定中的行为差异。

0 个答案:

没有答案