views:

203

answers:

3

Hello. I have next control template in my WPF app.

    <Style TargetType="Label" x:Key="LabelStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Label">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="40"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <TextBox x:Name="MyTextBlock" Text="{TemplateBinding Content}"  Height="20" HorizontalAlignment="Left"  VerticalAlignment="Top" />
                        <Label Content="{TemplateBinding Content}" Grid.Column="1" Grid.Row="1"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

TextBox "MyTextBlock" is invisible in C# code of window. How can I access to this textblock in code

A: 

You can do a similar thing that XAML pages do in the code behind (except for you need to do it in OnApplyTemplate override):

public override void OnApplyTemplate() {
    base.OnApplyTemplate();

    var MyTextBlock = this.GetTemplateChild("MyTextBlock")
}

EDIT Just noticed that MyTextblock is actually a TextBox, so casting a TextBox to TextBlock will cause an exception. Try the updated code.

Igor Zevaka
İgor it's not work. My ControlTemplate in Window.Resources. I paste your code in my app and set breakpoint to check variable.But MyTextBlock variable stay null. What I make wrong?
Polaris
Did you set the style on the label in XAML? Like so: `<Label Style="{StaticResource LabelStyle}"/>`
Igor Zevaka
Of course I set it.
Polaris
Try `(TextBlock)this.FindName("MyTextBlock");`
Igor Zevaka
I check your code again. It not works.
Polaris
I understand it and use correct cast to TextBox but findName method return null
Polaris
`GetTemplateChild` seems to work even though MSDN recommends against it. Will look into it.
Igor Zevaka
A: 

I found some solution for my situation. I just use loaded event of TextBox in my ControlTemplate

    private void MyTextBlock_Loaded(object sender, RoutedEventArgs e)
    {
        TextBox txt = sender as TextBox;
        if (txt!=null)
         {
            Messagebox.Show("It works");
         }

    }

But it is not so beautiful solution.

Polaris
No! obviously, that is not elegant. In addition to that, can you tell me the need to access that particular textbox so that i can tell you an alternate solution as accessing elements by name from codebehind is hardly recommended.
Veer
I can tell you. I want to hide TextBox is some situation and show it when I need it. That why I want to get instance of TextBox for manipulate with his Visibility property.
Polaris
You can use bind your visibility property in xaml rather for that using BindingConverter if required. If you could tell me the conditions on which the visibility is dependent, i think i could draw it up clearly.
Veer
I have some static class with static bool property "isFieldCodesEnabled". Before to open window i check value of this property: is true - then I show my textBox, if false I hide it.
Polaris
+2  A: 

Try binding your property to the textbox's visibility directly

<TextBox Visibility="{Binding IsFieldCodesEnabled, Converter={StaticResource BoolToVis}}" />

where BoolToVis is defined as:

<Resouces> 
    <loc:BooleanToVisibilityConverter k:key="BoolToVis"/> 
</Resources>
Veer
Yes! The bottom line is that if you are trying to access the TextBox in code in this scenario, you are almost certainly doing something very wrong. This is a great answer because it shows the right way to do this. I would give you +10 if I could.
Ray Burns
I like this solution. Pure and understandable. !!
Polaris