我有一个使用可观察集合作为数据源的组合框,我希望“虚拟”值为“无”作为框中的第一项,因为它控制对其他数据源的过滤器。
其他数据绑定对象也使用相同的可观察集合,因此无法直接向数据源添加“无”值,因为我不想要,例如,我的数据网格中包含“无”。 另外,我宁愿避免过滤器只为那些不使用它的人删除“none”值,因为我希望observable集合直接反映数据库数据;如果可能的话。 我还想避免每个数据绑定控件有一个可观察的集合。
我真正想要的是将一个非数据绑定的第一个条目放入组合框中,同时将项目源指向一个可以修复的集合。
由于
/编辑: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>
答案 0 :(得分: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.
}
答案 1 :(得分:0)