【问题标题】:WPF Make dropdown expanded when it becomes visibleWPF 使下拉菜单在可见时展开
【发布时间】:2016-04-30 12:21:50
【问题描述】:

我有一个自定义下拉菜单和两个或更多单选按钮:当第一个单选按钮被勾选时,下拉菜单被隐藏,当任何其他单选按钮被勾选时,下拉菜单可见并允许用户选择项目(例如,无线电所有项目、选定项目、选定的主要项目)。

当用户点击第二个或第三个收音机时,我需要默认展开下拉菜单(因此下拉菜单变得可见并立即展开)。

我有一个可行的方法,但它似乎不符合 WPF 的良好做法:

XAML:

<layout:MultiSelectCaseTypeComboBoxEdit
            IsVisibleChanged="CaseTypesComboBox_OnIsVisibleChanged"
            EditValue="{Binding Path=SelectedCaseTypes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
....
/>

*.xaml.cs:

    private void CaseTypesComboBox_OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var cb = sender as MultiSelectCaseTypeComboBoxEdit;
        cb.IsPopupOpen = cb.IsVisible;
    }

如您所见,在 IsVisibleChanged 事件中,我使下拉列表的 IsPopupOpen 值等于它的可见性。

但我的问题是,如何在 WPF 方法方面使用触发器/行为,而无需 *.xaml.cs 文件中的任何额外代码?

更新 1: 下面是基本控件样式的代码:

<Style TargetType="{x:Type layoutControls:EditableMultiSelectComboBoxEdit}" 
       x:Key="{x:Type layoutControls:EditableMultiSelectComboBoxEdit}"
       BasedOn="{StaticResource {x:Type editors:ComboBoxEdit}}">
    <Style.Triggers>
        <Trigger Property="SelectedItemDeleted" Value="True">
            <Setter Property="ToolTip" Value="The selected item(s) was delete. Click to refresh"/>
            <Setter Property="BorderTemplate">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ContentControl}">
                        <Border BorderThickness="1" BorderBrush="Red">
                            <ContentPresenter/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>

如您所见,它在这里使用了一些删除逻辑,并且基于 DevExpress ComboBoxEdit 控件。

更新 2: 我通过这种方式添加了样式:

<layout:MultiSelectCaseTypeComboBoxEdit.Resources>
                <Style x:Key="EditableMultiSelectComboBoxEdit1" 
TargetType="layout:MultiSelectCaseTypeComboBoxEdit" />
            </layout:MultiSelectCaseTypeComboBoxEdit.Resources>
            <layout:MultiSelectCaseTypeComboBoxEdit.Style>
                <Style TargetType="layout:MultiSelectCaseTypeComboBoxEdit"
                     BasedOn="{StaticResource EditableMultiSelectComboBoxEdit1}">

也试过这个:

<layout:MultiSelectCaseTypeComboBoxEdit.Resources>
                <Style x:Key="EditableMultiSelectComboBoxEdit1" 
TargetType="{x:Type layout:MultiSelectCaseTypeComboBoxEdit}" />
            </layout:MultiSelectCaseTypeComboBoxEdit.Resources>
            <layout:MultiSelectCaseTypeComboBoxEdit.Style>
                <Style      TargetType="layout:MultiSelectCaseTypeComboBoxEdit"
                     BasedOn="{StaticResource EditableMultiSelectComboBoxEdit1}">

仍然遇到同样的错误。

在基本控件的样式中,它的键定义为

x:Key="{x:Type layoutControls:EditableMultiSelectComboBoxEdit}"

那么我该如何正确继承呢?

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    给你。您可以通过使用DataTrigger 来完成此操作,然后相应地设置IsPopupOpen 属性。

    <layout:MultiSelectCaseTypeComboBoxEdit
                EditValue="{Binding Path=SelectedCaseTypes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        <layout:MultiSelectCaseTypeComboBoxEdit.Style>
            <Style TargetType="layout:MultiSelectCaseTypeComboBoxEdit">
                <Setter Property="IsPopupOpen" Value="False" />
                <Style.Triggers>
                     <DataTrigger Binding="{Binding IsVisible, RelativeSource={RelativeSource Self}}" Value="True">
                        <Setter Property="IsPopupOpen" Value="True" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </layout:MultiSelectCaseTypeComboBoxEdit.Style>            
    </layout:MultiSelectCaseTypeComboBoxEdit>
    

    编辑:

    您也可以使用BasedOn 保持基本样式。

    <Style TargetType="layout:MultiSelectCaseTypeComboBoxEdit" BasedOn="{StaticResource MyBaseStyle}">
    

    其中MyBaseStyle 是用于基本控件的样式的资源。

    编辑2:

    如果您无法从基本样式创建 Key,请尝试:

    <Style TargetType="layout:MultiSelectCaseTypeComboBoxEdit" BasedOn="{StaticResource {x:Type editors:ComboBoxEdit}}">
    

    【讨论】:

    • 谢谢。它确实在扩展下拉列表,但这是我现在到达那里的内容:take.ms/qsoMJ(而不是值,它只显示类型,然后在关闭时崩溃)。我发现为所有 ComboBoxEdit 的基类设置了另一种样式。 - 可能是错误行为的原因。我会在描述中添加它的代码。是否可以将您建议的样式添加到控件而不覆盖基本控件的样式?
    • 我已将此添加到控件中: BasedOn="{StaticResource {x:Type layout:EditableMultiSelectComboBoxEdit}}" 但问题仍然存在。您有什么想法可能是这里的原因吗?
    • 你需要基于样式,而不是类型。
    • 仍然无法使其正常工作。我已经用我尝试过的方法添加了更新 2。您能否检查一下并告诉我在添加样式时做错了什么?如我所见,基本样式基于 Type: BasedOn="{StaticResource {x:Type editors:ComboBoxEdit}}" 我应该如何处理才能使其正常工作?谢谢。
    • 您需要将样式引用为 Key,而不是 Type。见这里:msdn.microsoft.com/en-us/library/…
    【解决方案2】:

    最终对我有用的解决方案包括使用 WPF 行为:

    XAML:

        <layout:MultiSelectCaseTypeComboBoxEdit>
            <i:Interaction.Behaviors>
                <behaviors:ComboboxExpandingBehavior/>
            </i:Interaction.Behaviors>
        </layout:MultiSelectCaseTypeComboBoxEdit>
    

    行为代码:

    public class ComboboxExpandingBehavior : Behavior<EditableMultiSelectComboBoxEdit>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.IsVisibleChanged += OnVisibleChanged;
        }
    
        protected override void OnDetaching()
        {
            AssociatedObject.IsVisibleChanged -= OnVisibleChanged;
            base.OnDetaching();
        }
    
        private void OnVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            var cb = sender as EditableMultiSelectComboBoxEdit;
    
            if (cb != null)
            {
                cb.IsPopupOpen = cb.IsVisible;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-06-18
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 2022-11-13
      • 2014-04-24
      • 2014-07-15
      • 2018-10-22
      • 1970-01-01
      相关资源
      最近更新 更多