【问题标题】:Styling of ComboBox elementsComboBox 元素的样式
【发布时间】:2017-11-06 09:57:58
【问题描述】:

我有一个ComboBox 绑定到一个ObservableCollection<ElementType> 集合。我想要将 Name 和 Type 属性都设置为 null 的不可选择的分隔符。当名称设置为字符串并且类型为空时,我希望它是一个不可选择的标题/标题。否则,我希望这些元素是可选元素,但要留出一点边距。

这是我目前的位置:

我的两个问题是:

  • 所选项目显示为具有完整名称空间的 ElementType 对象,而不是名称字符串。
  • 已启用元素的突出显示不再显示在 MouseOver 上。

XAML:

<ComboBox Grid.Column="1" Grid.Row="2" Style="{StaticResource ElementTypeComboBoxStyle}"
            ItemsSource="{Binding Path=Element.ElementTypeList}"
            SelectedItem="{Binding Path=Element.SelectedElementType}">
    <ComboBox.Resources>
        <converters:NullToBooleanConverter x:Key="NullToBooleanConverter" />
    </ComboBox.Resources>
    <ComboBox.ItemContainerStyle>
        <Style TargetType="{x:Type ComboBoxItem}">
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=Name, Converter={StaticResource NullToBooleanConverter}}" Value="True" />
                        <Condition Binding="{Binding Path=Type, Converter={StaticResource NullToBooleanConverter}}" Value="True" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="IsEnabled" Value="False" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                                <Separator HorizontalAlignment="Stretch" />
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </MultiDataTrigger>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=Name, Converter={StaticResource NullToBooleanConverter}}" Value="False" />
                        <Condition Binding="{Binding Path=Type, Converter={StaticResource NullToBooleanConverter}}" Value="True" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="IsEnabled" Value="False" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                                <TextBlock Text="{Binding Path=Name}" />
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </MultiDataTrigger>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=Name, Converter={StaticResource NullToBooleanConverter}}" Value="False" />
                        <Condition Binding="{Binding Path=Type, Converter={StaticResource NullToBooleanConverter}}" Value="False" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="IsEnabled" Value="True" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                                <TextBlock Text="{Binding Path=Name}" Margin="10,0,0,0" />
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>

C#:

public class ElementType {
    public ElementType(string name, Type type) {
        Name = name;
        Type = type;
    }
    public string Name { get; private set; }
    public Type Type { get; private set; }
}

private static ObservableCollection<ElementType> _elementTypeList = new ObservableCollection<ElementType> {
    // Controls
    new ElementType("Controls:", null),
    new ElementType("Analog Output Slider", typeof(AnalogOutputSliderControl)),
    new ElementType("Digital Output Button", typeof(DigitalOutputButtonControl)),

    new ElementType(null, null),  // Separator

    // Indicators
    new ElementType("Indicators:", null),
    new ElementType("Numeric Value", typeof(NumericValueIndicator)),
    new ElementType("ROV Illustration", typeof(RovIllustration)),
    new ElementType("Trend Graph", typeof(TrendGraphIndicator)),

    new ElementType(null, null),  // Separator

    // Generic element
    new ElementType("None", typeof(Element))
};
[XmlIgnore]
public static ObservableCollection<ElementType> ElementTypeList { get { return _elementTypeList; } }

【问题讨论】:

  • 第一个问题可以通过使用不同的文本模板和下拉模板来解决,请参阅this question。至于第二个 - 目前还不清楚你想要什么。此外,此解决方案如何与箭头键选择(无下拉菜单)一起使用?
  • 正如@Sinatr 指出的那样,这是模板选择器的完美场景。
  • 保持突出显示的最简单解决方案是不要禁用任何东西,而只是阻止例如在验证期间将分隔符设置为SelectedItem。这也适用于箭头键。
  • @Sinatr 我不想使用模板选择器。不过,我喜欢你上一篇文章中的想法。但我无法让它工作,因为它在鼠标悬停时都会突出显示分隔符和标题,而且我无法阻止选择分隔符或标题。您能否详细说明一下答案?

标签: c# wpf


【解决方案1】:

我选择不使用模板选择器,因为我认为它对我的需求来说有点沉重。我在 XAML 中找到了解决问题的方法,得到了以下结果。它也适用于箭头键,因为分隔符和标题被禁用。只有“问题”是标题的灰色,但我暂时保留它。

XAML:

<ComboBox Grid.Column="1" Grid.Row="2" Style="{StaticResource ElementTypeComboBoxStyle}"
            ItemsSource="{Binding Path=Element.ElementTypeList}"
            SelectedItem="{Binding Path=Element.SelectedElementType}">
    <ComboBox.Resources>
        <converters:NullToBooleanConverter x:Key="NullToBooleanConverter" />
    </ComboBox.Resources>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=Name}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
    <ComboBox.ItemContainerStyle>
        <Style TargetType="{x:Type ComboBoxItem}">
            <Setter Property="IsEnabled" Value="False" />
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=Name, Converter={StaticResource NullToBooleanConverter}}" Value="True" />
                        <Condition Binding="{Binding Path=Type, Converter={StaticResource NullToBooleanConverter}}" Value="True" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                                <Separator HorizontalAlignment="Stretch" />
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </MultiDataTrigger>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=Name, Converter={StaticResource NullToBooleanConverter}}" Value="False" />
                        <Condition Binding="{Binding Path=Type, Converter={StaticResource NullToBooleanConverter}}" Value="False" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="IsEnabled" Value="True" />
                    <Setter Property="Padding" Value="10,0,0,0" />
                </MultiDataTrigger>                            
            </Style.Triggers>
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    • 2016-11-21
    • 2018-06-07
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多