Stopbyte

How to open Popup on other WPF TextBlock element click event trigger, using XAML only?

I’ve got two controls, a TextBlock and a Popup. When the user clicks (MouseDown) on the TextBlock, I want to display the Popup.

I thought that I could do this with an EventTrigger on the Popup, but I couldn’t use setters in an EventTrigger, I can only start storyboards. I want to do this strictly in XAML, because the two controls are in a template and I don’t know how I’d find the popup in code.

This is what conceptually I want to do, but can’t because you can’t put a setter in an EventTrigger (like you can with a DataTrigger):

<TextBlock x:Name="CCD">Some text</TextBlock>
 
<Popup>
    <Popup.Style>
        <Style>
            <Style.Triggers>
                <EventTrigger SourceName="CCD" RoutedEvent="MouseDown">
                    <Setter Property="Popup.IsOpen" Value="True" />
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </Popup.Style>
    
    <!-- The rest of the popup content -->
</Popup>

What is the best way to show a popup strictly in XAML when an event happens on a different control?

3 Likes

Use a ToggleButton, but you can style a ToggleButton with a TextBlock template to make it look like one.

I used a typical ToggleButton, which I restyled as a textblock by changing its control template. Then I just bound the IsChecked property on the ToggleButton to the IsOpen property on the popup. Popup has some properties like StaysOpen that let you modify the closing behavior.

The following XAML snippet works for me:

<StackPanel>
  <ToggleButton Name="button"> 
    <ToggleButton.Template>
      <ControlTemplate TargetType="ToggleButton">
        <TextBlock>Click Me Here!!</TextBlock>
      </ControlTemplate>      
    </ToggleButton.Template>
  </ToggleButton>
  <Popup IsOpen="{Binding IsChecked, ElementName=button}" StaysOpen="False">
    <Border Background="LightYellow">
      <TextBlock>I'm the popup</TextBlock>
    </Border>
  </Popup> 
 </StackPanel>
3 Likes

another way to do it:

<Border x:Name="Bd" 
        BorderBrush="{TemplateBinding BorderBrush}" 
        BorderThickness="{TemplateBinding BorderThickness}" 
        Background="{TemplateBinding Background}" 
        Padding="{TemplateBinding Padding}" 
        SnapsToDevicePixels="true">
    <StackPanel>
        <Image  Source="{Binding ProductImage,RelativeSource={RelativeSource TemplatedParent}}" 
                Stretch="Fill" Width="65" Height="85"/>
        <ContentPresenter   HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        <Button x:Name="myButton" Width="40" Height="10">
            <Popup Width="100" Height="70" IsOpen="{Binding ElementName=myButton,Path=IsMouseOver, Mode=OneWay}">
                <StackPanel Background="Yellow">
                    <ItemsControl ItemsSource="{Binding Produkt.SubProducts}"/>
                </StackPanel>
            </Popup>
        </Button>
    </StackPanel>
</Border>
1 Like