Sudhakar Singh
Sudhakar Singh

Reputation: 389

how to create binding in code when the datatemplate is declared in xaml

i have a datatemplate declared in xaml.
for e.g.

    <DataTemplate x:Key="TestTemplate">
        <StackPanel>
            <TextBox Name="txtBox"  Visibility="Visible"></TextBox>                
        </StackPanel>             
    </DataTemplate>

I wish to set the binding for txtBox in code behind before the element is generated because i have different binding paths for different elements that get generated

I can get the template in the code behind as :

DataTemplate tmplt = FindResource("TestTemplate") as DataTemplate;

but i am not sure what to do next. How to get the the txtBox reference to set the binding.

Upvotes: 1

Views: 3070

Answers (2)

Vinit Sankhe
Vinit Sankhe

Reputation: 19885

We have to remember one thing that Templates are not instantiated UI controls. They are streamed obejcts in XAML and are shared between UI elements. So if you edit a dataTemplate and change its stucture (by adding, editing, deleting an element under the template) it would change the one data template which is shared among controls. Thus other elements using that template will also be affected by the change.

Now lets address your issue of adding a dynamic biding to a textbox. You say each generated textbox will have different binding paths. So this definitely does NOT call for changing the data template itself!

You will have to access the text box and add dynamic bindings to it AFTER the textbox's is generated.

I see that your binding differs based on your "situation", so why cant you use TemplateSelector? Template selector will decide which data template (having one specific binding applied to the TetxBox) at runtime.

Upvotes: 3

stukselbax
stukselbax

Reputation: 5935

The first part of answer - is FindName() method.

example:

DataTemplate tmplt = FindResource("TestTemplate") as DataTemplate;
TextBox my = (TextBox)tmplt.FindName("txtBox");

try out this, it should help to get access to TextBox control. I think that you know how to bind to. If you want your DataBinding behave different way, use MultiBinding and Converter.

EDIT

public class GeneralObject
{
    private object someObject;
    public GeneralObject(object initObject)
    {
        this.someObject = initObject;
    }

    //If you want to bind to some text, for example
    public string Text
    {
        get
        {
            //I think you know which objects are coming as input
            if (this.someObject is SpecialClass1)
                return ((SpecialClass1)this.someObject).SpecialClass1TextProperty;
            if (this.someObject is SpecialClass2)
                return ((SpecialClass2)this.someObject).SpecialClass2TextProperty;
            //and so on.
        }
    }

}

EDIT 2 One more possible way

So I remember, that WPF have ContentControl!

<ContentControl Content="{Binding Path=CurrentObject}"/>

But in this case you have to create number of DataTemplate's, every Template for one class.

<DataTemplate DataType="{x:Type local:SpecialClass1}">
    ...
</DataTemplate>
<DataTemplate DataType="{x:Type local:SpecialClass2}">
    ...
</DataTemplate>
<!--and so on-->

WPF resolve DataTypes of ContentControl.Content property, and put to the ContentControl right DataTemplate.

Upvotes: 1

Related Questions