我需要创建一个带有嵌入式搜索/过滤功能的自定义下拉菜单,并通过创建一个在按下时会显示弹出窗口的按钮来实现。弹出窗口有一个项目列表框,并通过使用网格进行布局在顶部和底部显示一些按钮。我在这里为你简化了一点:
<UserControl x:Class="CustomDropDown"
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:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
mc:Ignorable="d" x:Name="Root"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Button x:Name="DropDownButton" Click="DropDownButton_Click" HorizontalContentAlignment="Stretch">
<DockPanel HorizontalAlignment="Stretch" LastChildFill="False" Margin="2,0">
<TextBlock DockPanel.Dock="Left" Text="{Binding ElementName=Root, Path=Header}"/>
<TextBlock DockPanel.Dock="Right" Text="▼"/>
</DockPanel>
</Button>
<Popup x:Name="DropDownPopup" Placement="Bottom" Focusable="False" StaysOpen="False"
Width="{Binding ElementName=DropDownButton, Path=ActualWidth}" MinWidth="250"
Height="Auto" AllowsTransparency="True">
<Border Padding="5" Background="White" Margin="0,0,8,8"
BorderBrush="Silver" CornerRadius="0,0,5,5" BorderThickness="1">
<Border.Effect>
<DropShadowEffect BlurRadius="5" Opacity="0.5"/>
</Border.Effect>
<Grid HorizontalAlignment="Stretch" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" MaxHeight="150" x:Name="DropDownList" SelectionMode="Extended"
ItemsSource="{Binding ElementName=Root, Path=ItemsSource}"
DisplayMemberPath="{Binding ElementName=Root, Path=DisplayMemberPath}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<!-- Item Style -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Grid>
<!-- More Columns Button Here -->
</Grid>
</Grid>
</Border>
</Popup>
</Grid>
</UserControl>
因为我将它设置为 UserControl,所以我有一些依赖属性,例如 Header、DisplayMemberPath 等,我希望能够在 XAML 中使用控件时定义绑定。 SelectedItems 有自己的依赖属性,并且在后面的代码中注册了一个事件以保持一切同步。
public IRangeCollection SelectedItems
{
get { return (IRangeCollection)GetValue(SelectedItemsProperty); }
set { SetValue(SelectedItemsProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedItems.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.Register("SelectedItems",
typeof(IRangeCollection), typeof(CustomDropDown),
new PropertyMetadata(new PropertyChangedCallback(SelectedItemsPropertyChanged)));
private static void SelectedItemsPropertyChanged(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
CustomDropDown dropDown = (CustomDropDown)sender;
dropDown.UpdateDropDownFromSelectedItems();
dropDown.UpdateSelectedItemsCollectionChangedHandler(e.OldValue, e.NewValue);
}
private void UpdateSelectedItemsCollectionChangedHandler(object oldValue, object newValue)
{
if (oldValue != null && oldValue is INotifyCollectionChanged)
{
((INotifyCollectionChanged)oldValue).CollectionChanged -= SelectedItems_CollectionChanged;
}
if (newValue != null && newValue is INotifyCollectionChanged)
{
((INotifyCollectionChanged)newValue).CollectionChanged += SelectedItems_CollectionChanged;
}
}