Поле со списком из нескольких элементов с заголовками? - PullRequest
9 голосов
/ 27 апреля 2011

Можно ли иметь «заголовки столбцов» в поле со списком, привязанные к нескольким элементам?Например, поле со списком, которое отображает имя человека.Поле со списком будет отображать Джона Доу.Но я хотел бы отобразить заголовки столбцов:

First   Last
John    Doe
Jane    Doe
Jimmy   Doe

Возможно ли это без использования сетки данных?Как насчет простого решения, которое включает использование сетки данных?Я нашел одно решение для встраивания сетки данных в поле со списком, но это выглядит сложно и требует MS Blend.

Я был бы рад, если бы я мог просто получить несколько заголовков в качестве первой строки в раскрывающемся списке.

G

Вот мой код xaml с попыткой HB, которая выдает ошибку компиляции, как упомянуто в комментариях.

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
<ComboBox Name="cboPlaceNames" Grid.IsSharedSizeScope="True" ItemsSource="{DynamicResource items}" Height="22" Width="285" Margin="0,6,165,0" SelectedIndex="0" HorizontalAlignment="Right" VerticalAlignment="Top" SelectionChanged="cboPlaceNames_SelectionChanged">
  <ComboBox.Resources>
    <CompositeCollection x:Key="items">
      <ComboBoxItem IsEnabled="False">
        <Grid TextElement.FontWeight="Bold">
          <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="A"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition SharedSizeGroup="B"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition SharedSizeGroup="C"/>
          </Grid.ColumnDefinitions>
          <Grid.Children>
            <TextBlock Grid.Column="0" Text="Name"/>
            <TextBlock Grid.Column="2" Text="CLLI"/>
            <TextBlock Grid.Column="4" Text="Street"/>
          </Grid.Children>
        </Grid>
      </ComboBoxItem>
      <Separator/>
      <CollectionContainer Collection="{Binding Source={x:Reference cboPlaceNames}, Path=DataContext.Data}"/>
    </CompositeCollection>

    <DataTemplate DataType="x:Type obj:PlaceName">
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition SharedSizeGroup="A"/>
          <ColumnDefinition Width="5"/>
          <ColumnDefinition SharedSizeGroup="B"/>
          <ColumnDefinition Width="5"/>
          <ColumnDefinition SharedSizeGroup="C"/>
        </Grid.ColumnDefinitions>
        <Grid.Children>
          <TextBlock Grid.Column="0" Text="{Binding Name}"/>
          <TextBlock Grid.Column="2" Text="{Binding CLLI}"/>
          <TextBlock Grid.Column="4" Text="{Binding Street}"/>
        </Grid.Children>
      </Grid>
    </DataTemplate>
  </ComboBox.Resources>
</ComboBox>      

Ответы [ 4 ]

16 голосов
/ 27 апреля 2011

Пример:

<ComboBox Name="cb" Grid.IsSharedSizeScope="True" ItemsSource="{DynamicResource items}">
    <ComboBox.Resources>
        <CompositeCollection x:Key="items">
            <ComboBoxItem IsEnabled="False">
                <Grid TextElement.FontWeight="Bold">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition SharedSizeGroup="A"/>
                        <ColumnDefinition Width="5"/>
                        <ColumnDefinition SharedSizeGroup="B"/>
                    </Grid.ColumnDefinitions>
                    <Grid.Children>
                        <TextBlock Grid.Column="0" Text="Name"/>
                        <TextBlock Grid.Column="2" Text="Occupation"/>
                    </Grid.Children>
                </Grid>
            </ComboBoxItem>
            <Separator/>
            <CollectionContainer Collection="{Binding Source={x:Reference cb}, Path=DataContext.Data}"/>
        </CompositeCollection>

        <DataTemplate DataType="{x:Type obj:Employee}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition SharedSizeGroup="A"/>
                    <ColumnDefinition Width="5"/>
                    <ColumnDefinition SharedSizeGroup="B"/>
                </Grid.ColumnDefinitions>
                <Grid.Children>
                    <TextBlock Grid.Column="0" Text="{Binding Name}"/>
                    <TextBlock Grid.Column="2" Text="{Binding Occupation}"/>
                </Grid.Children>
            </Grid>
        </DataTemplate>
    </ComboBox.Resources>
</ComboBox>

Обратите внимание, что получить право на связывание Collection не так просто, потому что нет ни DataContext, ни VisualTree, на которые можно положиться, ElementName и RelativeSource этого не делаютЭто связано с тем, что CompositeCollection - это просто коллекция, а не FrameworkElement.

Кроме того, это выполняется с помощью гридов, имеющих столбцы общего размера.DataTemplate применяется автоматически с помощью DataType.

screenshot

Редактировать: Недостаточно установить свойство IsHitTestVisible для header-ComboBoxItem в Falseтак как он все еще может быть выбран с помощью клавиатуры.Теперь я изменил его на IsEnabled="False", что немного затухает.Вы могли бы, вероятно, изменить шаблон этого элемента, чтобы не делать этого.Или если вы найдете другой способ отключить его от выбора, который, конечно, тоже сработает.

2 голосов
/ 12 марта 2015

Самый простой способ добавить заголовки столбцов в комбинированный список - это использовать просмотр списка в комбинированном списке. Следующий код дает решение для этого.

            <ComboBox HorizontalAlignment="Center" 
                      IsTextSearchEnabled="False" Width="200"                                            
                      IsEditable="True" Text="{Binding }"> 
                 <ListView ItemsSource="{Binding YOURITEMSOURCE}" 
                        SelectedItem="{Binding Path=SELECTEDITEMSOURCE}"
                         Height="200" ScrollViewer.VerticalScrollBarVisibility="Visible">                  
                           <ListView.View>
                               <GridView>
                                  <GridViewColumn Width="130"  Header="Name" DisplayMemberBinding="{Binding Name}"   />
                                  <GridViewColumn Width="130" Header="Occupation" DisplayMemberBinding="{Binding Occupation}" />
                                  <GridViewColumn Width="130"  Header="Age" DisplayMemberBinding="{Binding Age}" />
                                  <GridViewColumn Width="130" Header="Salary" DisplayMemberBinding="{Binding Salary}" />
                               </GridView>
                           </ListView.View>
                  </ListView>

            </ComboBox>
0 голосов
/ 05 февраля 2016

Мне нравится ответ HB , но, к сожалению, когда я его использую, я вижу ошибки привязки данных в выходных данных для свойств ComboBoxItem * HorizontalContentAlignment и VerticalContentAlignment:

Не удается найти источник для привязки со ссылкой 'RelativeSource FindAncestor, AncestorType =' System.Windows.Controls.ItemsControl ', AncestorLevel =' 1 ''.BindingExpression: Path = HorizontalContentAlignment;DataItem = NULL;целевым элементом является ComboBoxItem (Name = '');Свойство target - «HorizontalContentAlignment» (тип «HorizontalAlignment»)

Они не приводят к аварийному завершению программы, но они загромождают вывод и вызывают заметные задержки при выполнении отладочных сборок.Все, что их вызывает, кажется, глубоко в недрах ComboBox или ComboBoxItem;в любом случае, я не мог придумать, как их предотвратить (установка этих свойств вручную или через Style не помогла).Так что я закончил с небольшим изменением.Это длиннее и хакернее, чем мне бы хотелось, но оно выполняет свою работу:

<ComboBox Name="cb" Grid.IsSharedSizeScope="True" ItemsSource="{DynamicResource items}">
 <ComboBox.Resources>
    <!-- We'll use this dummy value to represent the header row. -->
    <!-- The type and value are arbitrary; we just need a unique type -->
    <!-- for DataTemplate selection to work with. -->
    <system:Int32 x:Key="HeaderPlaceholder">-1</system:Int32>

    <CompositeCollection x:Key="items">
      <StaticResource ResourceKey="HeaderPlaceholder" />
      <CollectionContainer Collection="{Binding Source={x:Reference cb},
         Path=DataContext.Data}"/>
    </CompositeCollection>

    <!-- DataTemplate for the header item -->
    <DataTemplate DataType="{x:Type system:Int32}">
      <DataTemplate.Resources>
        <!-- Make the TextBlocks black even though they are disabled -->
        <Style TargetType="TextBlock">
          <Style.Triggers>
            <Trigger Property="IsEnabled" Value="False">
              <Setter Property="Foreground" Value="Black" />
            </Trigger>
          </Style.Triggers>
        </Style>
      </DataTemplate.Resources>

      <StackPanel>
        <Grid TextElement.FontWeight="Bold">
          <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="A"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition SharedSizeGroup="B"/>
          </Grid.ColumnDefinitions>
          <Grid.Children>
              <TextBlock Grid.Column="0" Text="Name"/>
              <TextBlock Grid.Column="2" Text="Occupation"/>
          </Grid.Children>
        </Grid>
        <Separator />
      </StackPanel>
    </DataTemplate>

    <!-- DataTemplate for a normal, selectable item -->
    <DataTemplate DataType="{x:Type obj:Employee}">
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition SharedSizeGroup="A"/>
          <ColumnDefinition Width="5"/>
          <ColumnDefinition SharedSizeGroup="B"/>
        </Grid.ColumnDefinitions>
        <Grid.Children>
          <TextBlock Grid.Column="0" Text="{Binding Name}"/>
          <TextBlock Grid.Column="2" Text="{Binding Occupation}"/>
        </Grid.Children>
      </Grid>
    </DataTemplate>
  </ComboBox.Resources>

  <ComboBox.ItemContainerStyle>
    <!-- Make sure the header item is disabled so it can't be selected -->
    <Style TargetType="ComboBoxItem">
      <Style.Triggers>
        <Trigger Property="DataContext" Value="{StaticResource HeaderPlaceholder}">
          <Setter Property="IsEnabled" Value="False" />
        </Trigger>
      </Style.Triggers>
    </Style>
  </ComboBox.ItemContainerStyle>
</ComboBox>
0 голосов
/ 18 апреля 2012

Примените следующий стиль к ComboBox.

<Style x:Key="ListViewComboBox" TargetType="{x:Type ComboBox}">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" 
                         Color="LightBlue"/>
    </Style.Resources>
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="FontFamily" Value="Arial"/>
    <Setter Property="FontSize" Value="12"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Margin" Value="0"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBox}">
                <Border Background="{TemplateBinding Background}" 
                        BorderBrush="{TemplateBinding BorderBrush}" 
                        BorderThickness="{TemplateBinding BorderThickness}"
                        CornerRadius="3"
                        SnapsToDevicePixels="True">
                    <Grid>
                        <Border x:Name="Border">
                            <Popup x:Name="PART_Popup" AllowsTransparency="true" IsOpen="{TemplateBinding IsDropDownOpen}" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Focusable="False">
                                <Border x:Name="Shdw" 
                                        MaxHeight="{TemplateBinding MaxDropDownHeight}" 
                                        MinWidth="{Binding ActualWidth, ElementName=Border}">
                                    <Border x:Name="DropDownBorder" 
                                            Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" 
                                            BorderBrush="{TemplateBinding BorderBrush}" 
                                            BorderThickness="1">
                                        <ListView KeyboardNavigation.DirectionalNavigation="Contained"
                                                  ItemsSource="{TemplateBinding ItemsSource}"
                                                  SelectedItem="{Binding Mode=TwoWay, Path=SelectedItem, RelativeSource={RelativeSource Mode=TemplatedParent}}"
                                                  View="{TemplateBinding Tag}"/>
                                    </Border>
                                </Border>
                            </Popup>
                        </Border>
                        <DockPanel Margin="2">
                            <FrameworkElement DockPanel.Dock="Right"
                                              Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
                            <Border x:Name="SelectedItemBorder" Margin="{TemplateBinding Padding}">
                                <Grid>
                                    <ContentPresenter Content="{TemplateBinding SelectionBoxItem}" 
                                                      ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" 
                                                      ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" 
                                                      ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                                      Margin="1,1,1,1" 
                                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                </Grid>
                            </Border>
                        </DockPanel>
                        <ToggleButton x:Name="DropDownToggleButton" 
                                      ClickMode="Press"
                                      Focusable="false" 
                                      Foreground="{TemplateBinding BorderBrush}"
                                      IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
                                      Margin="2"
                                      MinHeight="0" 
                                      MinWidth="0" 
                                      Width="Auto"/>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelectionBoxHighlighted" Value="true"/>
                            <Condition Property="IsDropDownOpen" Value="false"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                    </MultiTrigger>
                    <Trigger Property="IsSelectionBoxHighlighted" Value="true">
                        <Setter Property="Background" TargetName="SelectedItemBorder" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                    </Trigger>
                    <Trigger Property="HasItems" Value="false">
                        <Setter Property="MinHeight" TargetName="DropDownBorder" Value="95"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                    </Trigger>
                    <Trigger Property="IsGrouping" Value="true">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                    </Trigger>
                    <Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
                        <Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/>
                    </Trigger>
                    <Trigger Property="IsReadOnly" Value="True">
                        <Setter Property="Visibility" TargetName="DropDownToggleButton" Value="Collapsed"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsEditable" Value="true">
            <Setter Property="IsTabStop" Value="false"/>
            <Setter Property="Padding" Value="1"/>
            <Setter Property="Template" Value="{StaticResource ComboBoxEditableTemplate}"/>
        </Trigger>
    </Style.Triggers>
</Style>

Примените нужный вам вид к свойству Tag ComboBox

<ComboBox ItemsSource={Binding Items}>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <!-- Enter your item template shown as the selected item. -->
        </DataTemplate>
    </ComboBox.ItemTemplate>
    <ComboBox.Tag>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Name}"
                            Header="Name" 
                            Width="100"/>
        </GridView>
    </ComboBox.Tag>
</ComboBox>

Это все люди.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...