I'm trying to understund how datacontex is passed to usercontrols.
I have 2 classes:
public class OuterClass
{
public InnerClass inner {get; set;}
}
public class InnerClass
{
public void targetFun()
{
//do something
}
}
And the Main Window class
public class MainWindow: Window
{
public OuterClass outer {get; set;}
//...
}
In the main window xaml file the DataContext is set to be the Outer class
<Window <!-- Properties --> >
<Grid DataContext="{Binding outer}">
<MyControl DataContext="{Binding inner}">
<!-- Here I do more stuff from outer class -->
</Grid>
</Window>
And this would be the definition of my UserControl
<UserControl x:Class="my:MyControl">
<Grid>
<TextBlock MouseDown="targetFun">Click me!</TextBlock>
</Grid>
</UserControl>
When I try to compile I get the error that the function "targetFun"
does not exist in 'MyControl'
it means that the compiler does not realize im trying to set the context in inner. How do I do that.
Sorry for the simple code I can't show the real one but this is pretty much what i'm doing. Thanks!
Edit: Typo
In WPF, Binding
uses the control's DataContext
as its context. For example,
<Grid DataContext="{Binding outer}">
<local:MyControl DataContext="{Binding inner}">
inner
is a member of the value of outer
. This example is a little funny because at the time when {Binding inner}
is evaluated (or whatever), the DataContext
of that Grid
is outer
, inherited from its parent. But then the binding sets it to something else. I avoid such things; I'm taking your word for it that it works at all.
Anyhow. Where's the binding on MouseDown
here?
<TextBlock MouseDown="targetFun">Click me!</TextBlock>
Nowhere. That's not a regular property that you're binding a viewmodel property to, hence the TextBlock
's DataContext
is irrelevant. That's an event, and are (or should be) giving it an event handler. Events are different (because they are, that's why). Since there's no {Binding ...}
, it's not looking for a property of the DataContext
; it's looking for an event handler method on the codebehind class. Delete ="targetFun"
there, type ="
after MouseDown
, and it'll prompt you to create an event handler on the codebehind class.
You can call targetFun()
like this in the event handler:
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
((sender as FrameworkElement).DataContext as InnerClass)?.targetFun();
}