Combined item Item source = ObservableCollection & I need the dummy entry "-None-" at the top

I have a combo box using the observable collection as the data source, and I want the dummy value of None as the first element in the field, as it controls the filters against other data sources.

Other database objects also use the same observable collection, so adding the value "No" directly to the data source is not possible, because I do not want, for example, my data having "no" in them. Also, I would prefer to avoid filters, just to remove the “none” value for those that don't use it, since I would like the observable collection to match the database data; if at all possible. I would also like to avoid having one observable collection for data management.

What I really need is to bind non-data-related data, the first entry in the combo box, and also the source of the source pointing to the protected collection.

thank

/ EDIT: XAML, which I use, but it does not close the combo box when clicking on the first item

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

+3
2

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.
}
+2
0

Source: https://habr.com/ru/post/1740911/


All Articles