如何在后面的代码中访问silverlight控件的datacontext

时间:2010-11-11 11:32:23

标签: silverlight

我有一个像我这样实例化的银色控件:

<MyControls:SomeControl DataContext="{Binding}" />

在此文件的代码隐藏中,如何访问此datacontext? this.DataContext等于null。

编辑(更多信息):

我正在为现有的silverlight应用程序构建扩展。我与应用程序集成的观点如下:

<DataTemplate x:Key="AnImportantIdentifierUsedByTheHostApp">
    <MyControls:SomeControl DataContext="{Binding}" />
</DataTemplate>

在我的控制范围内,我可以像这样绑定属性:

<Hyperlink NavigateUri="{Binding Path=UriWithSlug}">

这一切都很好。但是对于某些功能(具体来说,我需要使用WebBrowser控件和NavigateToString()方法),我需要从DataContext访问属性。

基本上在代码隐藏中,我需要做一些有效的事情:

myWebBrowser.NavigateToString(DataContext.MyHTMLStringProperty);

4 个答案:

答案 0 :(得分:3)

您不需要DataContext={Binding},因为这等于DataContext = DataContext

但是你缺少的是类型信息。绑定使用反射来解析属性路径,但是在代码隐藏中,您需要知道DataContext返回的对象的类型。

如果你能确定,那就简单地说: -

myWebBrowser.NavigateToString(((MyType)DataContext).MyHTMLString); 

如果您无法确定类型和/或您无法说服控制控件主机的任何人确保至少实现了与已知成员的特定接口,那么您可能需要自己求助于反射

使用绑定系统为您进行反射

如果您不能仅知道属性的类型,则可以选择另一种方法: -

public string HTMLString
{
   get { return (string)GetValue(HTMLStringProperty); }
   set { SetValue(HTMLStringProperty, value); }
}
public static DependencyProperty HTMLStringPropery =
   DependencyProperty.Register(
      "HTMLString",
      typeof(string),
      typeof(SomeControl),
      null);

现在,如果您确定知道要绑定的属性的名称,可以在控件构造函数的代码中设置绑定: -

SetBinding(HTMLStringProperty, new Binding("MyHTMLString"));

有了这个,您的代码将如下所示: -

myWebBrowser.NavigateToString(HTMLString);

或者,您可以将控件的这个新属性绑定到Xaml的责任: -

<DataTemplate x:Key="AnImportantIdentifierUsedByTheHostApp">                  
    <MyControls:SomeControl HTMLString="{Binding MyHTMLString}" />                  
</DataTemplate> 

答案 1 :(得分:1)

答案当然是超级直接的,我确信每个人都可能认为我在做......

在控件的Loaded事件被触发之前,DataContext不可用。

public MyUserControl() {
    var dc = this.DataContext // DataContext is null here in the ctor.

    this.Loaded += (s, e) => {
        var sc2 = this.DataContext // Loaded event fires, DataContext exists!
    };
}

同样,我确信这对很多SL开发者来说可能是显而易见的,但它完全绊倒了我。

答案 2 :(得分:0)

好的,现在更有意义了。相应地改变答案......

基本上你永远不需要DataContext = {Binding}。父控件设置项目的DataContext(每个项目)。在大多数由ItemsSource中的条目生成的列表类型控件中。

  1. 您可以删除DataContext = {Binding}并检查它是否仍然有效吗?
  2. 如果实际的子控件本身没有显式的DataContext值,那么要获取父控件的DataContext,您可能需要向上导航可视树(直到找到非null的DataContext)。
  3. 你能提供更多我们在上下文中看到的代码/ xaml吗?

答案 3 :(得分:0)

var mytype = this.DataContext as MyType;

作为预防措施,我会在之后检查null:

if (mytype!=null)
{
    // do something here
    myWebBrowser.NavigateToString(mytype.MyHTMLStringProperty);
}