有什么方法可以将分隔符添加到数据绑定的 WPF 组合框中吗? 即在我的 xaml 中,组合框的 ItemsSource="{Binding TheList}"。 该列表是一个可观察的对象集合,我想将其中一个与其余对象分开。 该列表也是从 sql 生成的,因此它不是硬编码或任何东西。 我也不希望分隔符是可选择的。 谢谢!
我正在 .cs 文件中动态构建组合框,并且没有使用绑定,但我相信它可以帮助您。分隔符无法单击和选择。
ComboBox frameColor = new ComboBox()
{
Width = 200,
Margin = new Thickness(180, -780, 0, 0),
VerticalAlignment = VerticalAlignment.Center,
IsEditable = false,
Items =
{
new ComboBoxItem(){...},
new Separator(),
new ComboBoxItem(){...},
new ComboBoxItem(){...},
new ComboBoxItem(){...},
new Separator(),
new ComboBoxItem(){...},
new ComboBoxItem(){...},
new ComboBoxItem(){...},
new ComboBoxItem(){...},
new ComboBoxItem(){...},
}
虽然我的
ComboxBox
(目前)不是DataBound
,但我通过向元素添加底部边框来实现分隔符的概念。在此示例中,分隔符之前两行和之后两行。
<ComboBox x:Name="Cbx" SelectionChanged="Cbx_SelectionChanged">
<ComboBoxItem Content="select one..." Foreground="DarkGray" IsSelected="True" /
<ComboBoxItem Content="ABC" />
<ComboBoxItem Content="DEF" />
<ComboBoxItem Content="GHI" BorderBrush="Black" BorderThickness="0,0,0,2" />
<ComboBoxItem Content="KLM" />
<ComboBoxItem Content="NOP" />
</ComboBox>
每个项目的 XAML 唯一解决方案。如果始终是相同的项目列表,您可能可以基于
ItemsControl
AlternationCount
添加触发器。
这就是结果。
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="BorderBrush" Value="DarkGray" />
<Setter Property="BorderThickness" Value="0,1,0,0" />
</Style>
</ComboBox.ItemContainerStyle>
您需要使用 ComboBox.ItemTemplate 来绘制您的项目
http://www.silverlightshow.net/items/Silverlight-ComboBox.aspx
如果您想在 C# 代码中执行相同操作:
Cbx.Items.Add("ABC");
Cbx.Items.Add("DEF");
ComboBoxItem item = new ComboBoxItem();
item.Content = "GHI";
item.BorderBrush = Brushes.Black;
item.BorderThickness = new Thickness(0, 0, 0, 2);
Cbx.Items.Add(item);
Cbx.Items.Add("KLM");
Cbx.Items.Add("NOP");
您所需要做的就是将 ComboBox 项目与数据项目分开。 您可以通过创建一个属性来实现此目的,该属性从 getter 构建 vstruct,并返回对象集合。 只需确保当您的数据发生更改时,也触发 ComboItems 属性的 PropertyChanged 事件。
这是一个小示例,它创建一个包含版本集合的组合框,顶部有一个标签和分隔符控件。
您可以将
SelectedComboItem
的类型设置为与您的数据类型相同,但如果所选项目的类型不匹配,它将失效并显示无效样式。
// Header Label and Separator to display at top of ComboBox
private object[] _defaultComboItems = new object[] { new Label() { Content = "Versions"}, new Separator() };
// Property that builds the structure for the ComboBox.
public IEnumerable<object>? ComboItems
=> Versions == null
? _defaultComboItems
: _defaultComboItems.Concat(Versions);
// Observable collection for the data items
private ObservableCollection<Version> _versions;
public ObservableCollection<Version> Versions
{
get => _versions;
set
{
if (_versions != value)
{
if (_versions != null)
{
_versions.CollectionChanged -= signalComboItemsChanged;
}
// Notify that Versions and ComboItems are changing.
OnPropertyChanging(nameof(ComboItems));
OnPropertyChanging(nameof(Versions));
_versions = value;
// Notify that Versions and ComboItems have changed.
OnPropertyChanged(nameof(Versions));
OnPropertyChanged(nameof(ComboItems));
if (value != null)
{
// Subscribe to CollectionChanged to rebuild ComboItems when Versions changes.
value.CollectionChanged += signalComboItemsChanged;
}
}
// Callback to signal ComboItems changes.
void signalComboItemsChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged(nameof(ComboItems));
}
}
}
// Selected item in the ComboBox, which can be a control or data item.
private object? _selectedComboItem;
public object? SelectedComboItem
{
get => _selectedComboItem;
set
{
if (_selectedComboItem != value)
{
OnPropertyChanging(nameof(SelectedComboItem));
_selectedComboItem = value;
OnPropertyChanged(nameof(SelectedComboItem));
}
}
}
// Property to retrieve selected data item.
public Version? SelectedVersion
=> SelectedComboItem as Version;
<ComboBox ItemsSource="{Binding ComboItems}"
SelectedItem="{Binding SelectedComboItem}"/>