Поле со списком Элемент source = ObservableCollection и мне нужна фиктивная запись '-None-' вверху - PullRequest
3 голосов
/ 13 апреля 2010

У меня есть поле со списком, использующее наблюдаемую коллекцию в качестве источника данных, и я хочу, чтобы «фиктивное» значение «None» было первым элементом в блоке, так как оно управляет фильтрами для других источников данных.

Другие объекты, связанные с данными, также используют ту же наблюдаемую коллекцию, поэтому добавление значения «None» непосредственно к источнику данных невозможно, так как я не хочу, например, для моих сетей данных, имеющих «none». Кроме того, я бы предпочел избегать фильтров, чтобы просто удалить значение «none» для тех, кто его не использует, так как я бы хотел, чтобы наблюдаемая коллекция прямо отражала данные базы данных; если вообще возможно. Я также хотел бы избежать наличия одной наблюдаемой коллекции на элемент управления с привязкой к данным.

Что мне действительно нужно, так это поместить первую запись в поле со списком без привязки к данным, а также указав источник элемента на доступную для сбора коллекцию.

Спасибо

/ EDIT: XAML, который я сейчас использую, но не закрывает поле со списком при нажатии на фиктивный первый элемент

<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>    

Ответы [ 2 ]

2 голосов
/ 30 апреля 2010

Вы можете обернуть ObservableCollection, что позволит вам использовать ComboBox без изменений. Оболочка будет выглядеть примерно так:

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.
}
0 голосов
/ 13 апреля 2010
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...