2012-07-19 60 views
1

此问题可能与Creating an instance of a nested class in XAML重复。此问题和相关的MSDN文档涉及嵌套类型。在这个例子中,类型本身并不是嵌套的,但是语法似乎很熟悉。我是否不知道是否有理由提出单独的问题和答案。引用XAML中的嵌套属性

我想使用ObjectDataProvider访问嵌套属性。我可以访问类型的静态属性,但通过类型上的静态属性访问实例属性会导致编译错误。

例如,采取以下三个类。

public static class A 
{ 
    static A() 
    { 
     BProperty = new B(); 
    } 

    public static B BProperty { get; private set; } 
} 

public class B 
{ 
    public B() 
    { 
     CProperty = new C(); 
    } 

    public C CProperty { get; private set; } 

    public string GetValue(string arg) 
    { 
     return arg + " from B"; 
    } 
} 

public class C 
{ 
    public string GetValue(string arg) 
    { 
     return arg + " from C"; 
    } 
} 

创造BPropertyObjectDataProviderA可以使用以下XAML来完成。

<Window.Resources> 
    <ObjectDataProvider x:Key="provider" 
         ObjectInstance="{x:Static Member=local:A.BProperty}" 
         MethodName="GetValue"> 
     <ObjectDataProvider.MethodParameters> 
     <System:String>string argument</System:String> 
     </ObjectDataProvider.MethodParameters> 
    </ObjectDataProvider> 
</Window.Resources> 
<Grid> 
    <Label Content="{Binding Source={StaticResource provider}}" /> 
</Grid> 

运行此代码会生成一个带有文本“B的字符串参数”的标签。

如果我将providerObjectInstance设置为"{x:Static Member=local:A.BProperty.CProperty}""{x:Static Member=local:A.BProperty+CProperty}"我收到编译错误。

我如何从ObjectDataProvider访问的BProperty实例?

+0

您的课程和属性名称相同。为了测试,你可以重命名你的类,看看它是否仍然存在? – Xcalibur37 2012-07-19 22:00:44

+0

这个例子是从我原来的代码简化的,它的属性名称与它们的返回类型不同。在这种情况下,问题仍然存在。但是,这可能会提高此示例的可读性,因此我将更新代码。 – bozalina 2012-07-19 22:07:25

+0

我会说这是因为B被实例化为静态。因此,一旦它被实例化,它的上下文属性就被忽略了。 – Xcalibur37 2012-07-19 22:23:41

回答

1

你能做的最好的是这样的:

<Window.Resources> 
    <ObjectDataProvider x:Key="provider" 
        ObjectType="{x:Type local:A}" 
        MethodName="GetCValue"> 
     <ObjectDataProvider.MethodParameters> 
      <System:String>string argument</System:String> 
     </ObjectDataProvider.MethodParameters> 
    </ObjectDataProvider> 
</Window.Resources> 


public class A 
{ 
    public A() 
    { 
     BProperty = new B(); 
    } 

    public B BProperty { get; private set; } 

    public string GetCValue(string arg) 
    { 
     return BProperty.CProperty.GetValue(arg); 
    } 
} 

public class B 
{ 
    public B() 
    { 
     CProperty = new C(); 
    } 

    public C CProperty { get; private set; } 

    public string GetValue(string arg) 
    { 
     return arg + " from B"; 
    } 
} 

public class C 
{ 
    public string GetValue(string arg) 
    { 
     return arg + " from C"; 
    } 
} 

我就从静态远离在这种类型的实现给定的的ObjectDataProvider

如果你想使用分层对象的性质,考虑实现MVVM模式并改为在ViewModel中实现所有对象。

上的ObjectDataProvider看看这篇文章了解详情: http://msdn.microsoft.com/en-us/magazine/cc163299.aspx

+0

这也是我到达的解决方案。我希望能有办法直接做到这一点。由于DataObjectProvider的性质,您提到远离静态。你能澄清这个原因吗? – bozalina 2012-07-20 00:39:08

+0

好吧,为了公平,我有点主观。这是因为我在大多数实现中看到了基于实例的用法。对于你正在做的事情,我个人只会使用MVVM,因为它在ViewModel的初始设置开销后给我提供了最大的灵活性。 – Xcalibur37 2012-07-20 00:42:36

1

做,在2个步骤:

<Window.Resources> 
    <ObjectDataProvider x:Key="providerOfC" 
         ObjectInstance="{x:Static Member=local:A.BProperty}" 
         MethodName="get_CProperty" /> 

    <ObjectDataProvider x:Key="provider" 
         ObjectInstance="{StaticResource providerOfC}" 
         MethodName="GetValue"> 
     <ObjectDataProvider.MethodParameters> 
     <System:String>string argument</System:String> 
     </ObjectDataProvider.MethodParameters> 
    </ObjectDataProvider> 
</Window.Resources> 
<Grid> 
    <Label Content="{Binding Source={StaticResource provider}}" /> 
</Grid> 

providerOfC让你尽可能A.BProperty.CProperty

provider然后调用GetValue("string argument")实例。