views:

61

answers:

1

I have an ObjectDataProvider in my XAML that references a method in my Window-deriving class. That is, I have NewForm.xaml.cs with class NewForm and the ObjectDataProvider in NewForm.xaml is referencing a method in NewForm. Currently, with the following XAML, I get a stack overflow error because the NewForm constructor keeps getting called over and over again:

<Window x:Class="MyNamespace.NewForm" ...>
<Window.Resources>
<ObjectDataProvider x:Key="getTeamName"
                    ObjectType="{x:Type local:NewForm}"
                    MethodName="GetTeamName">
    <ObjectDataProvider.MethodParameters>
        <sys:Int32>-1</sys:Int32>
    </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
</Window>

I'm guessing it's because the ObjectType is set to NewForm, so it loads NewForm to load my application, but then it has to create a new instance of NewForm in order to call GetTeamName, but the constructor calls InitializeComponent which creates a new NewForm which has to create a new NewForm to call GetTeamName... It actually crashes Visual Studio 2010 every time.

Anyway, what I'm asking is do I have to define methods that my XAML calls via ObjectDataProviders in some other class? Or can I somehow use ObjectDataProvider with a method defined in my XAML's class? Or to call a method in my XAML's class, should I be using some other XAML besides ObjectDataProvider? It doesn't seem like I can put my C# method in another class since it uses TryFindResource to get an XmlDataProvider from my XAML.

+1  A: 

The root of the problem here is that ObjectDataProvider always creates a new instance of whatever object it's created for. So yes, it will create an instance of the NewForm class, whose constructor will instantiate another ObjectDataProvider that creates an instance of the NewForm class, and then it's turtles all the way down.

But the thing is, ObjectDataProvider is really just a way to declare create objects and call methods on them in XAML, so that you don't have to do it in code-behind. Since you're already creating the object in code-behind, avoiding code-behind isn't benefiting you. So just have the method that creates the object also add it to the window's resource dictionary:

// this method no longer needs to return anything, so you can change its signature
private void GetTeamName()
{
    // code that creates the object goes here.
    // and now, instead of "return myObject", do this:
    Resources.Add("getTeamOName");
}
Robert Rossney