【问题标题】:Combobox ItemsControl to show property of SelectedItems collection组合框 ItemsControl 以显示 SelectedItems 集合的属性
【发布时间】:2019-01-25 09:37:42
【问题描述】:

我有一个组合框,它使用一种样式来允许使用列表框进行多项选择(如果需要,问题底部的完整样式)。控件绑定到ObservableCollection<Foo>Foo 有点像这样:

public class Foo
{
    ComplexOtherClass Complex { get; set; }
    string Label { get; set; }
}

样式中列表框的绑定如下所示:

<....
    <ListBox x:Name="lstBox"
        ItemsSource="{TemplateBinding ItemsSource}"
        DisplayMemberPath="Label">            
    </ListBox>
..../>

这给了我一个很好的正确显示的字符串标签集合。问题是组合框顶部的控件模板不“知道”显示每个SelectedItems 的标签,因此它只显示每个选定项目的命名空间和类。

<ItemsControl x:Name="showMe" 
              ItemsSource="{Binding SelectedItems, ElementName=lstBox}">        
</ItemsControl>

如何更改样式以使 ItemsControl 显示所选项目的 Label 属性?

我在 Google 上没有找到任何可以帮助我的东西 - 任何涉及多选组合框的搜索似乎都只是展示了如何制作一个,而没有解决这个特定问题!

这是完整的样式(抱歉所有静态资源,但希望结构仍然足够有意义以有用)

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Brushes_Colours_rsrc.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="20" />
            </Grid.ColumnDefinitions>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Normal" />
                    <VisualState x:Name="MouseOver">
                        <Storyboard>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                          Storyboard.TargetName="Border">
                                <EasingColorKeyFrame KeyTime="0"
                                   Value="{StaticResource ControlMouseOverColor}" />
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Pressed" />
                    <VisualState x:Name="Disabled">
                        <Storyboard>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                          Storyboard.TargetName="Border">
                                <EasingColorKeyFrame KeyTime="0"
                                   Value="{StaticResource GlyphColor}" />
                            </ColorAnimationUsingKeyFrames>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                                          Storyboard.TargetName="Arrow">
                                <EasingColorKeyFrame KeyTime="0"
                                   Value="{StaticResource DisabledForegroundColor}" />
                            </ColorAnimationUsingKeyFrames>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                          Storyboard.TargetName="Border">
                                <EasingColorKeyFrame KeyTime="0"
                                   Value="{StaticResource DisabledBorderDarkColor}" />
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
                <VisualStateGroup x:Name="CheckStates">
                    <VisualState x:Name="Checked">
                        <Storyboard>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                          Storyboard.TargetName="Border">
                                <EasingColorKeyFrame KeyTime="0"
                                   Value="{StaticResource ControlPressedColor}" />
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Unchecked" />
                    <VisualState x:Name="Indeterminate" />
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Border x:Name="Border"
            Grid.ColumnSpan="2"
            CornerRadius="2"
            BorderThickness="1">
                <Border.BorderBrush>
                    <LinearGradientBrush EndPoint="0,1"
                             StartPoint="0,0">
                        <GradientStop Color="{DynamicResource BorderLightColor}"
                        Offset="0" />
                        <GradientStop Color="{DynamicResource BorderDarkColor}"
                        Offset="1" />
                    </LinearGradientBrush>
                </Border.BorderBrush>
                <Border.Background>

                    <LinearGradientBrush StartPoint="0,0"
                             EndPoint="0,1">
                        <!--button fill-->
                        <LinearGradientBrush.GradientStops>
                            <GradientStopCollection>
                                <GradientStop Color="{DynamicResource ControlLightColor}" />
                                <GradientStop Color="{DynamicResource ControlMediumColor}"
                            Offset="1.0" />
                            </GradientStopCollection>
                        </LinearGradientBrush.GradientStops>
                    </LinearGradientBrush>

                </Border.Background>
            </Border>
            <Border Grid.Column="0"
            CornerRadius="2,0,0,2"
            Margin="1" >
                <Border.Background>
                    <SolidColorBrush Color="{DynamicResource ControlLightColor}"/>
                </Border.Background>
            </Border>
            <Path x:Name="Arrow"
          Grid.Column="1"
          HorizontalAlignment="Center"
          VerticalAlignment="Center"
          Data="M 0 0 L 4 4 L 8 0 Z" >
                <Path.Fill>
                    <SolidColorBrush Color="Green"/>
                </Path.Fill>
            </Path>
        </Grid>
    </ControlTemplate>
    <ControlTemplate x:Key="ComboBoxTextBox"
                 TargetType="{x:Type TextBox}">
        <Border x:Name="PART_ContentHost"
          Focusable="False"
          Background="Green" />
    </ControlTemplate>
    <Style x:Key="MyMultiComboBox" TargetType="{x:Type ComboBox}">
        <Setter Property="SnapsToDevicePixels" Value="true" />
        <Setter Property="OverridesDefaultStyle" Value="true" />
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
        <Setter Property="ScrollViewer.CanContentScroll" Value="true" />
        <Setter Property="MinWidth" Value="120" />
        <Setter Property="MinHeight" Value="20" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBox}">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="MouseOver" />
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ColorAnimationUsingKeyFrames Storyboard.TargetName="PART_EditableTextBox"
                                                Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
                                            <EasingColorKeyFrame KeyTime="0" Value="{StaticResource DisabledForegroundColor}" />
                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="EditStates">
                                <VisualState x:Name="Editable">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="PART_EditableTextBox">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ContentSite">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}" />
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Uneditable" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ToggleButton x:Name="ToggleButton"
                                              Template="{StaticResource ComboBoxToggleButton}"
                                              Grid.Column="2"
                                              Focusable="false"
                                              ClickMode="Press"
                                              IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>
                        <ItemsControl x:Name="showMe" IsHitTestVisible="false" Style="{StaticResource Text_NormalText}" ItemsSource="{Binding SelectedItems, ElementName=lstBox}" Margin="1,0,22,0">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel IsItemsHost="True" Orientation="Horizontal"/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                        </ItemsControl>
                        <ContentPresenter x:Name="ContentSite"
                                          IsHitTestVisible="False"
                                          Content="{TemplateBinding SelectionBoxItem}"
                                          ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
                                          ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                                          Margin="3,3,23,3"
                                          VerticalAlignment="Stretch"
                                          HorizontalAlignment="Left">
                        </ContentPresenter>
                        <TextBox x:Name="PART_EditableTextBox"
                                 Style="{x:Null}"
                                 Template="{StaticResource ComboBoxTextBox}"
                                 HorizontalAlignment="Left"
                                 VerticalAlignment="Bottom"
                                 Margin="3,3,23,3"
                                 Focusable="True"
                                 Background="Transparent"
                                 Visibility="Hidden"
                                 IsReadOnly="{TemplateBinding IsReadOnly}" />
                        <Popup x:Name="Popup"
                                       Placement="Bottom"
                                       IsOpen="{TemplateBinding IsDropDownOpen}"
                                       AllowsTransparency="True"
                                       Focusable="False"
                                       PopupAnimation="Slide">
                            <Grid x:Name="DropDown"
                                          SnapsToDevicePixels="True"
                                          MinWidth="{TemplateBinding ActualWidth}"
                                          MaxHeight="{TemplateBinding MaxDropDownHeight}">
                                <Border x:Name="DropDownBorder" BorderThickness="1">
                                    <Border.BorderBrush>
                                        <SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
                                    </Border.BorderBrush>
                                    <Border.Background>
                                        <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
                                    </Border.Background>
                                </Border>
                                <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
                                    <!--<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />-->
                                    <ListBox x:Name="lstBox"
                                             Background="{StaticResource DarkGreenBackground}"
                                             Style="{StaticResource Text_NormalText}"
                                             TextBlock.FontSize="12"
                                             SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                             KeyboardNavigation.DirectionalNavigation="Contained" SelectionMode="Multiple"
                                             ItemsSource="{TemplateBinding ItemsSource}"
                                             DisplayMemberPath="Label"
                                             >
                                    </ListBox>
                                </ScrollViewer>
                            </Grid>
                        </Popup>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasItems" Value="false">
                            <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95" />
                        </Trigger>
                        <Trigger Property="IsGrouping" Value="true">
                            <Setter Property="ScrollViewer.CanContentScroll" Value="false" />
                        </Trigger>
                        <Trigger SourceName="Popup" Property="AllowsTransparency" Value="true">
                            <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4" />
                            <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
        <Setter Property="SnapsToDevicePixels" Value="true" />
        <Setter Property="OverridesDefaultStyle" Value="true" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                    <Border x:Name="Border"
                                    Padding="2"
                                    SnapsToDevicePixels="true"
                                    Background="Transparent">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="SelectionStates">
                                <VisualState x:Name="Unselected" />
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                            <EasingColorKeyFrame KeyTime="0" Value="{StaticResource Good}" />
                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="SelectedUnfocused">
                                    <Storyboard>
                                        <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                            <EasingColorKeyFrame KeyTime="0" Value="{StaticResource SelectedUnfocusedColor}" />
                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ContentPresenter />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

编辑 尝试绑定文本块而不是 ItemsControl 失败 - 文本块中未显示任何内容。

<Style.Resources>
    <base:CollectionToStringConverter x:Key="ToList"/>
</Style.Resources>

...和...

<....
<TextBlock x:Name="showMe" IsHitTestVisible="False"
           TextTrimming="CharacterEllipsis"
           Background="HotPink" Foreground="Black"
           DataContext="{Binding SelectedItems,ElementName=lstBox}"
           Text="{Binding SelectedItem.Label,Converter={StaticResource ToList}}"
           Margin="1,1,22,1">
</TextBlock>
....>

【问题讨论】:

  • 应该是 Text="{Binding SelectedItems, ElementName=lstBox, Converter={StaticResource ToList}}" 并删除 DataContext。转换器应返回所有标签的字符串连接。

标签: c# wpf


【解决方案1】:

您将DisplayMemberPath 属性用于ListBox,为什么不对选择框做同样的事情?

<ItemsControl x:Name="showMe" 
              ItemsSource="{Binding SelectedItems, ElementName=lstBox}"
              DisplayMemberPath="Label">        
</ItemsControl>

但实际上你不需要ItemsControl,也许是一个简单的TextBlockFooListToLabels 值转换器?

【讨论】:

  • 我希望能够使用文本块来访问 TextTrimming 功能,但不确定如何引用 SelectedItems 集合以使文本框的内容显示所有项目...我想显示一个逗号分隔的列表,但这是我的解决方案...您将如何使用文本框实现此目的?
  • 查看这个将 TextBlock 绑定到列表:stackoverflow.com/questions/345385/…
  • 在转换器的速成课程之后(感谢您指点我),我快到了,但只是坚持实施 - 我只是注释掉 ItemsControl 并在其位置放置一个 Textblock?我似乎无法将它放在样式中的正确位置...
猜你喜欢
  • 2015-08-25
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-17
相关资源
最近更新 更多