-1

I have the following XAML markup, in which I am embedding a couple of <Image> tags inside a <StackPanel>, inside a <Grid>, inside a <ControlTemplage>:

<Window.Resources>
    <Style...>
        ...
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabControl}">
                    <Grid ...>
                        ...
                        <StackPanel Grid.Row="1" Orientation="Horizontal" FlowDirection="RightToLeft">
                            <Image x:Name="connectedFlag" ... />
                            <Image x:Name="disconnectedFlag" ... />
                        </StackPanel>
                    </Grid>
                </ControlTemplate>
            </Setter>
        </Setter>
    </Style>
</Window.Resources>

I can see in the preview window in Visual Studio that these images are displayed correctly inside the <Grid> in the <ControlTemplate> on my GUI, however, I now want to access the images from inside my C#, so that I can call functions to show/ hide the images depending on whether my application is connected to a server or not.

I have a continuousThread() method in my C#, in which I am trying to set the Visibility property of connectedFlag & disconnectedFlag depending on which condition is met, i.e.

if(condition){
    disconnectedFlag.Visibility = Visibility.Visible;
    connectedFlag.Visibility = Visibility.Hidden;
}else{
    disconnectedFlag.Visibility = Visibility.Hidden;
    connectedFlag.Visibility = Visibility.Visible;
}

However, I get a couple of compile errors in my C# that say:

The name 'disconnectedFlag' does not exist in the current context The name 'connectedFlag' does not exist in the current context

Why can't I reference my 'flag' variables from inside the .xaml.cs file? Anyone have any suggestions?

Noble-Surfer
  • 3,052
  • 11
  • 73
  • 118
  • Possible duplicate of [How do I access an element of a control template from within code-behind](http://stackoverflow.com/questions/8126700/how-do-i-access-an-element-of-a-control-template-from-within-code-behind) – ASh May 16 '16 at 18:45

2 Answers2

0

Imagine for a moment that that template is instantiated twice, or nineteen times, or 300. That's the default case for templates in WPF. Which disconnectedFlag would you expect that name to refer to when you have 300 of them in different places? There's no way to make the call. What if it hasn't been instantiated at all yet? What you're trying to do is an absurdity.

What you're trying to do should be done with triggers in the ControlTemplate.

<ControlTemplate TargetType="{x:Type TabControl}">
    <Grid ...>
        ...
        <StackPanel Grid.Row="1" Orientation="Horizontal" FlowDirection="RightToLeft">
            <Image x:Name="connectedFlag" ... />
            <Image x:Name="disconnectedFlag" ... />
        </StackPanel>
    </Grid>
    <ControlTemplate.Triggers>
        <DataTrigger Binding="{Binding Condition}" Value="True">
            <Setter TargetName="connectedFlag" Value="Hidden" />
            <Setter TargetName="disconnectedFlag" Value="Visible" />
        </DataTrigger>
        <DataTrigger Binding="{Binding Condition}" Value="False">
            <Setter TargetName="connectedFlag" Value="Visible" />
            <Setter TargetName="disconnectedFlag" Value="Hidden" />
        </DataTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Condition should be exposed on your viewmodel as a property that raises PropertyChanged when its value changes. If you don't have a viewmodel, we can define it on your view and work out a different binding for it that'll work that way.

0

So the issue was to do with where in the XAML I was placing the <Image> tags... To get rid of the compile errors, and place the images in the location I wanted on the GUI, I moved the images outside the <StackPanel> & <TabItem> tags, but kept them inside the <Grid>:

<Grid>
    <Image...>... </Image>
    <TabControl...>
        <TabItem...>
            <StackPanel ...>
Noble-Surfer
  • 3,052
  • 11
  • 73
  • 118