How to access the datacontext of a silverlight control in a codeb

I have a silverlight control that I create like this:

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

In the code code of this file, how can I access this datacontext? this.DataContext is null.

Edit (more):

I am creating an extension for an existing Silverlight application. My point at which I integrate the application is as follows:

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

Inside my control, I can bind to the following properties:

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

And all this works great. However, for some functions (in particular, I need to use the WebBrowser control and the NavigateToString () method), I need to access the properties from the DataContext.

Basically in the code, I need to do something to:

 myWebBrowser.NavigateToString(DataContext.MyHTMLStringProperty); 
+4
source share
4 answers

The answer is of course super straight forward, and I'm sure everyone probably guessed what I was doing ...

DataContext is not available until the Loaded control event occurs.

 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! }; } 

Again, I'm sure this is probably obvious to many SL developers, but it completely turned me off.

+1
source

You do not need DataContext={Binding} , as this is equivalent to DataContext = DataContext .

However, you do not have enough type information. Bindings use reflection to resolve property paths; however, when encoding, you need to know the type of object returned by the DataContext .

If you can be sure of this, it will be simple: -

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

If you cannot be sure of the type and / or cannot convince those who control the host of your controls in order to provide at least a certain interface with known members, then you may need to resort to reflection.

Use the snap system to make a reflection for you

An alternative if you cannot know the type is just the name of the property: -

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

Now, if you are sure that you know the name of the property you want to bind, you can configure the code binding in your control constructor: -

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

With this in place, your code will look like this: -

 myWebBrowser.NavigateToString(HTMLString); 

Alternatively, you can attach this new property of your control to Xaml's liability: -

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

Ok, now it makes a little more sense. Changing the answer accordingly ...

Basically, you'll never need DataContext = {Binding}. The DataContext of the element is set (for each element) by the parent control. Most list controls that are generated from entries in an ItemsSource.

  • Can you remove DataContext = {Binding} and verify that it still works?
  • If the actual child control does not have an explicit DataContext value, then to get the parent control's DataContext, you may need to navigate the visual tree (until you find a non-zero DataContext).

Can you provide more / xaml code, we can see above in context?

0
source
 var mytype = this.DataContext as MyType; 

As a precaution, I will check for null after:

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

All Articles