WPF Custom ControlTemplate for ListBox with Popup closes the popup

37 views Asked by At

I'm trying to create a custom control with custom template called MultiSelectableDropdown derived from ListBox.

What I wanted to do is, put ListBoxItems inside a Popup using ItemsPresenter like it should be (i guess)

But, everytime when I make a selection, popup disappears. IsPopupOpen does not change, it just disappears.

NOTE: Yes, I know StaysOpen="true" will make the popup visible all the time but, it is not a good solution.

 internal class MultiSelectableDropdown : ListBox
 {
     public bool IsPopupOpen
     {
         get { return (bool)GetValue(IsPopupOpenProperty); }
         set { SetValue(IsPopupOpenProperty, value); }
     }

     public static readonly DependencyProperty IsPopupOpenProperty = DependencyProperty.Register(nameof(IsPopupOpen), typeof(bool), typeof(MultiSelectableDropdown), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

     public RelayCommand ClearSelection { get; set; }

     public MultiSelectableDropdown()
     {
         SelectionMode = SelectionMode.Multiple;

         ClearSelection = new RelayCommand((_) => SelectedItems.Clear());
     }
 }

Here is the template

    <Style TargetType="{x:Type dropdowns:MultiSelectableDropdown}">
        <Setter Property="Background" Value="White"/>
        <Setter Property="BorderBrush" Value="{StaticResource  Gray-300}"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="Padding" Value="{StaticResource Thickness-2-1-5}"/>
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <UniformGrid Rows="3" Columns="4"/>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Foreground" Value="{StaticResource Zinc-700}"/>
                    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                <controls:SpacedStackPanel SpaceX="3" Orientation="Horizontal" Background="{TemplateBinding Background}" Margin="7">
                                    <Border BorderThickness="1" BorderBrush="{StaticResource Zinc-300}"
                                            Background="White"
                                            x:Name="brd"
                                            Width="16" Height="16"
                                            CornerRadius="4">
                                        <misc:Icon x:Name="icon" IconCode="f00c" Foreground="{StaticResource Indigo-600}" Visibility="Collapsed" 
                                                   VerticalAlignment="Center"
                                                   HorizontalAlignment="Center"
                                        
                                                   />
                                    </Border>

                                    <ContentPresenter VerticalAlignment="Center" />
                                </controls:SpacedStackPanel>

                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsSelected" Value="True">
                                        <Setter TargetName="brd" Property="BorderBrush" Value="{StaticResource Indigo-600}" />
                                        <Setter TargetName="icon" Property="Visibility" Value="Visible" />
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type dropdowns:MultiSelectableDropdown}">
                    <Border BorderThickness="1"
                            CornerRadius="4" BorderBrush="{TemplateBinding BorderBrush}" 
                            Background="{TemplateBinding Background}"
                            VerticalAlignment="{TemplateBinding VerticalAlignment}"
                            HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                            Width="{TemplateBinding Width}"
                            ClipToBounds="True"
 >
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>


                            <ToggleButton x:Name="tgButton"
                                              Style="{StaticResource FlatToggleButton}"
                                              Content="adad"
                                              IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsPopupOpen, Mode=TwoWay}"
                                              Padding="{TemplateBinding Padding}" />

                            <Label Grid.Column="1" Content="{Binding ElementName=PART_Popup, Path=IsOpen, Mode=OneWay}" />


                            <Popup x:Name="PART_Popup"
                                            Grid.Column="0"
                                            Grid.ColumnSpan="2"
                                            
                                            StaysOpen="False"
                                            Placement="RelativePoint"
                                            
                                            IsOpen="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsPopupOpen, Mode=TwoWay}"
                                            MinWidth="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth, Mode=OneWay, FallbackValue=1}"
                                            VerticalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight, Mode=OneWay, FallbackValue=0}"
                                            >
                                <StackPanel>
                                    <ItemsPresenter />
                                    <!--<ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ItemsSource, Mode=OneWay}" />-->

                                    <Button 
                                        Content="clear" 
                                        HorizontalContentAlignment="Center" 
                                        Padding="3"
                                        Visibility="Collapsed"
                                        Command="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ClearSelection, Mode=OneWay}"
                                        />

                                </StackPanel>
                            </Popup>

                        </Grid>
                    </Border>
                  
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
0

There are 0 answers