Search code examples
c#wpfdatatemplate

Access DataTemplate controls in code behind


I have problem with this code:

<ListBox x:Name="lbInvoice" ItemsSource="{Binding ocItemsinInvoice}">
<ListBox.ItemTemplate>
    <DataTemplate>
        <StackPanel>
            <ToggleButton x:Name="btnInvoiceItem">
                <StackPanel Orientation="Horizontal">
                    <ToggleButton x:Name="btnInvoiceQuantity" Content="{Binding Quantity}"/>
                    <TextBlock Text="{Binding Item.ItemName}" Width="175" Padding="7,5,0,0"/>
                </StackPanel>
            </ToggleButton>
            <Popup x:Name="popQuantity" Closed="popQuantity_Closed" PlacementTarget="{Binding ElementName=btnInvoiceQuantity}" IsOpen="{Binding IsChecked,ElementName=btnInvoiceQuantity}">
                    <Grid>
                        <TextBlock x:Name="tbUnitPrice" Text="Unit Price"/>
                        <Button x:Name="btnClosePopup" Click="btnClosePopup_Click">
                    </Grid>
            </Popup>
        </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>

In code behind in btnClosePopup click event I can't access to popup to close it and do some other changes on it.

I have tried to use FindName() method but it doesn't work for me

var template = lbInvoice.Template;
var myControl = (Popup)template.FindName("popQuantity", lbInvoice);

Please can you help and tell me how do I access to controls that inside DataTemplate in code behind?


Solution

  • You have already to Open/Close this Popup in this line:

    IsOpen="{Binding IsChecked, ElementName=btnInvoiceQuantity}"
    

    As an alternative answer from @dkozl, you can close the Popup in such a way:

    <Popup x:Name="popQuantity" 
           IsOpen="{Binding Path=IsChecked, ElementName=btnInvoiceQuantity}">
    
        <Grid Width="200" Height="200" Background="Gainsboro">
            <TextBlock Text="Unit Price" />
    
            <ToggleButton x:Name="btnClosePopup" 
                          IsChecked="{Binding Path=IsChecked, ElementName=btnInvoiceQuantity}"
                          Content="Close"
                          Width="100" 
                          Height="30" />
        </Grid>
    </Popup>
    

    Or you can directly specify a property IsOpen of Popup:

    <ToggleButton x:Name="btnClosePopup"
                   IsChecked="{Binding Path=IsOpen, ElementName=popQuantity}" ... />
    

    But in this case at the background color of Button will be in state of IsChecked="True". To avoid this, without creating a new Template for your Control, you can use a system style of flat button:

    <ToggleButton x:Name="btnClosePopup"
                  Style="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}" ... />