You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF自定义ListBox派生控件选中项时Popup意外关闭问题求助

WPF自定义ListBox派生控件选中项时Popup意外关闭问题求助

各位大佬,我正在开发一个继承自ListBox的自定义控件MultiSelectableDropdown,想要通过ItemsPresenter把ListBoxItem放在Popup里展示,但遇到了一个棘手的问题:每次我选中一项时,Popup就会莫名消失,但绑定的IsPopupOpen属性值并没有发生变化。

我知道设置StaysOpen="true"可以让Popup一直保持显示状态,但这并不是一个合适的解决方案,希望能找到更合理的处理方式。

下面是我的控件后台代码:

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());
    }
}

对应的控件样式模板:

<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>

备注:内容来源于stack exchange,提问作者one_developer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 11:29:35