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>