Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wpf Popup placement

Tags:

c#

binding

wpf

Is there any chance I can place popup next to an item from ListBox? I use MVVM, list is bound to elements, and for some choosen elements I want to show popup next to the item.

I have list of elements and I want to show popup when I click on specified list element, but popup should be shown next to selected list item.

I tried something like this (it doesn't work):

    <Popup  IsOpen="{Binding Path=ShowPopup}" PlacementTarget="{Binding ElementName=List1, Path=SelectedItem}" Placement="Center">
        <TextBox Background="Red" Height="120" Text="Aaaaaa FUUUUUUUUUUUUU....."></TextBox>
    </Popup>

I don't want to use code behind, only xaml

like image 429
sba Avatar asked Oct 18 '10 22:10

sba


3 Answers

This will place a Popup to the right of the selected ListBoxItem

alt text

Example

<Window.Resources>
    <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />
    <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />

    <ControlTemplate x:Key="PopupListBoxItemTemplate" TargetType="ListBoxItem">
        <Border Name="Border" Padding="2" SnapsToDevicePixels="true">
            <Grid>
                <Popup Name="c_popup" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" >
                    <Border BorderBrush="Black" BorderThickness="1" CornerRadius="2.5">
                        <TextBlock Background="Wheat" Foreground="Black" Text="Aaaaaa FUUUUUUUUUUUUU....."/>
                    </Border>
                </Popup>
                <ContentPresenter />
            </Grid>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsSelected" Value="true">
                <Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
                <Setter TargetName="c_popup" Property="IsOpen" Value="True"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</Window.Resources>
<Grid>
    <ListBox Name="listBox"
             ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}">
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template" Value="{StaticResource PopupListBoxItemTemplate}" />
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
</Grid>
like image 74
Fredrik Hedblad Avatar answered Oct 08 '22 16:10

Fredrik Hedblad


The reason your example doesn't work is simply because you are binding the placement target to a non-ui object.

PlacementTarget="{Binding ElementName=List1, Path=SelectedItem}"

SelectedItem in this case could be a model/view model that represents an item in your list, therefor is not a correct usage of the PlacementTarget property.

What you need is to set the PlacementTarget to the ItemContainer (Dr. WPF explains) and this is not possible without the help of "some" codes.

Now that you know the problem, there are a few ways to make your code work so i'll leave it up to you.

like image 42
Tri Q Tran Avatar answered Oct 08 '22 17:10

Tri Q Tran


Since you want to show the popup when the item is clicked, will this work for you:

<Popup  IsOpen="{Binding Path=ShowPopup}" Placement="Mouse">
     <TextBox Background="Red" Height="120" Text="Aaaaaa FUUUUUUUUUUUUU....."></TextBox>
 </Popup>
like image 36
bufferz Avatar answered Oct 08 '22 18:10

bufferz