2010-04-13 13 views
3

J'ai une zone de liste déroulante utilisant une collection observable comme source de données et je veux une valeur "fictive" de "None" comme première élément dans la boîte car il contrôle les filtres contre d'autres sources de données. D'autres objets de données utilisent également la même collection observable. Par conséquent, l'ajout d'une valeur "None" directement à la source de données n'est pas possible car je ne veux pas, par exemple, mes DataGrid ayant un "none". Aussi, je préfère éviter les filtres pour supprimer simplement la valeur "none" pour ceux qui ne l'utilisent pas, car je voudrais que la collection observable reflète directement les données de la base de données; Si tout est possible. Je voudrais également éviter d'avoir une collection observable par contrôle de base de données. Ce que je suis vraiment après, c'est de mettre une première entrée, non liée aux données, dans une combobox tout en ayant la source de l'objet pointée sur une collection obervable.Zone de liste déroulante Point source = ObservableCollection & J'ai besoin d'une entrée factice '-Non-' en haut

Merci

/EDIT: XAML J'utilise maintenant, mais il ne ferme pas la zone de liste déroulante lorsque le premier élément fictif est cliqué

<ComboBox x:Class="TestManager.Controls.NullableComboBox" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:w="clr-namespace:System.Windows.Controls;assembly=PresentationFramework" 
     xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300" MouseUp="ComboBox_MouseUp"> 
<ComboBox.Resources> 
    <Geometry x:Key="DownArrowGeometry">M 0 0 L 3.5 4 L 7 0 Z</Geometry> 
    <Style x:Key="ComboBoxReadonlyToggleButton" TargetType="{x:Type ToggleButton}"> 
     <Setter Property="OverridesDefaultStyle" Value="true"/> 
     <Setter Property="IsTabStop" Value="false"/> 
     <Setter Property="Focusable" Value="false"/> 
     <Setter Property="ClickMode" Value="Press"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ToggleButton}"> 
        <Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"> 
         <Grid HorizontalAlignment="Right" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"> 
          <Path x:Name="Arrow" Fill="Black" HorizontalAlignment="Center" Margin="3,1,0,0" VerticalAlignment="Center" Data="{StaticResource DownArrowGeometry}"/> 
         </Grid> 
        </Microsoft_Windows_Themes:ButtonChrome> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsChecked" Value="true"> 
          <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/> 
         </Trigger> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

    <ControlTemplate x:Key="ComboBoxMessageTemplate" TargetType="{x:Type ComboBox}"> 
     <Grid x:Name="MainGrid" SnapsToDevicePixels="true"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*"/> 
       <ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/> 
      </Grid.ColumnDefinitions> 
      <Popup x:Name="PART_Popup" Margin="1" AllowsTransparency="true" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Grid.ColumnSpan="2"> 
       <Microsoft_Windows_Themes:SystemDropShadowChrome x:Name="Shdw" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=MainGrid}" Color="Transparent"> 
        <Border x:Name="DropDownBorder" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1"> 
         <ScrollViewer CanContentScroll="true"> 
           <StackPanel> 
            <TextBlock x:Name="SelectMessage" HorizontalAlignment="Left" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Tag}" VerticalAlignment="Center" Margin="{TemplateBinding Padding}" Visibility="Visible"/> 
           <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.DirectionalNavigation="Contained"/> 
           </StackPanel> 
          </ScrollViewer> 
        </Border> 
       </Microsoft_Windows_Themes:SystemDropShadowChrome> 
      </Popup> 
      <ToggleButton Style="{StaticResource ComboBoxReadonlyToggleButton}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/> 
      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" IsHitTestVisible="false" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/> 

     </Grid> 
     <ControlTemplate.Triggers> 
      <Trigger Property="SelectedItem" Value="{x:Null}"> 
       <Setter Property="Visibility" TargetName="SelectMessage" Value="Visible"/> 
      </Trigger>     
      <Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true"> 
       <Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/> 
       <Setter Property="Color" TargetName="Shdw" Value="#71000000"/> 
      </Trigger> 
      <Trigger Property="HasItems" Value="false"> 
       <Setter Property="Height" TargetName="DropDownBorder" Value="95"/> 
      </Trigger> 
      <Trigger Property="IsEnabled" Value="false"> 
       <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
       <Setter Property="Background" Value="#FFF4F4F4"/> 
      </Trigger> 
      <Trigger Property="IsGrouping" Value="true"> 
       <Setter Property="ScrollViewer.CanContentScroll" Value="false"/> 
      </Trigger> 
     </ControlTemplate.Triggers> 
    </ControlTemplate> 
</ComboBox.Resources>  

Répondre

0

Est-ce que cela vous aide 'Default' text for templated combo box

+0

Merci. Cela m'a permis d'y arriver. Maintenant, je dois forcer le menu déroulant à se fermer quand on clique sur l'élément fictif ... Des idées? – James

+0

dont la réponse avez-vous utilisé? – Amsakanna

+0

J'ai dû utiliser le premier dans ce post lié car le second repose sur la modification de l'itemource. Donc j'ai maintenant (avec quelques modifications) un bloc de texte dans mon menu déroulant qui, lorsqu'il est sélectionné, met l'index sélectionné à -1 .... Mais cliquer ne fait pas s'effondrer la zone de liste déroulante. – James

2

Vous pouvez encapsuler ObservableCollection, ce qui vous permet d'utiliser ComboBox non modifié. L'emballage devrait ressembler à ceci:

class PrefixedObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged 
{ 
    private readonly ObservableCollection<T> _wrappedCollection; 
    private readonly T _prefix; 

    public IEnumerator<T> GetEnumerator() 
    { 
     yield return _prefix; 
     foreach (T item in _wrappedCollection) 
      yield return item; 
    } 

    // ... Implement interfaces, etc. Forward along change notifications from wrapped collection. 
}