Vla*_*kov 15 wpf combobox autocomplete winforms drop-down-menu
我需要创建一个组合框
类似于Windows中的"运行"对话框.
可调整大小的完成清单:
下拉列表:
在WinForms,WPF或任何开源库中是否准备好了适当的控件?或者我需要使用低级控件手动实现它?
先感谢您!
WPF的解决方案
Part 1
原则上,您可以使用样式和模板来实现您的问题.在ComboBox
结果中给出Popup
,但默认情况下它不支持更改大小.如果您使用事件,添加调整大小并不困难DragDelta
.例:
private void MyThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
double yadjust = MyPopup.Height + e.VerticalChange;
double xadjust = MyPopup.Width + e.HorizontalChange;
if ((xadjust >= 0) && (yadjust >= 0))
{
MyPopup.Width = xadjust;
MyPopup.Height = yadjust;
}
}
Run Code Online (Sandbox Code Playgroud)
本次活动是最好的设置Thumb
控制(他也有事件DragStarted
,DragCompleted
).
这一切都很好,但我们确实需要在内部做ComboBox
.一种方法是使用Style
和Template
.首先,添加Thumb
样式ComboBox
,使其显示在展开的列表中:
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid Name="MainGrid">
<ToggleButton Name="ToggleButton" Template="{StaticResource ComboBoxToggleButton}" Grid.Column="2" Focusable="False" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" />
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3,3,23,3" VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox" Style="{x:Null}" Template="{StaticResource ComboBoxTextBox}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,3,23,3" Focusable="True" Background="{TemplateBinding Background}" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}" />
<!-- Expanded list store here -->
<Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
<Grid Name="DropDown" Width="100" Height="100" SnapsToDevicePixels="True">
<Border x:Name="DropDownBorder" Background="White" BorderThickness="1" BorderBrush="Gray" />
<ScrollViewer Margin="2" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
<!-- Our Thumb -->
<Thumb x:Name="ResizeGripThumb" Style="{StaticResource ResizeGripStyle}" HorizontalAlignment="Right" Margin="0,0,2,2" Background="Transparent" VerticalAlignment="Bottom" Width="12" Height="12" />
</Grid>
</Popup>
</Grid>
...
Run Code Online (Sandbox Code Playgroud)
对于正常显示Thumb
,添加样式为Path
:
<!-- ResizeGrip Style -->
<Style x:Key="ResizeGripStyle" TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Cursor" Value="SizeNWSE" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Grid>
<Path Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Stretch="Fill" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Fill="Gray" Data="M8,0L10,0 10,2 8,2z M4,4L6,4 6,6 4,6z M8,4L10,4 10,6 8,6z M0,8L2,8 2,10 0,10z M4,8L6,8 6,10 4,10z M8,8L10,8 10,10 8,10z "/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
现在,在这个阶段,我们已经ResizeGrip
在扩展列表中显示.但默认情况下ScrollBar
,然后用他的存在关闭它,所以它也定义了样式ScrollBar
.它会改变边际VerticalThumb
,因此:
...
<!-- VerticalThumb for ScollBar -->
<Style x:Key="VerticalThumb" TargetType="{x:Type Thumb}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Rectangle Fill="Gray" Margin="-1,-1,-3,16" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
现在,主要组件正常显示.ComboBox
在XAML中声明:
<ComboBox Name="ResizeComboBox" Style="{StaticResource MyComboBox}" IsEditable="True" IsTextSearchEnabled="True" FontSize="14" SelectedIndex="0" Width="100" Height="30">
<ComboBoxItem>1</ComboBoxItem>
<ComboBoxItem>2</ComboBoxItem>
<ComboBoxItem>3</ComboBoxItem>
<ComboBoxItem>4</ComboBoxItem>
<ComboBoxItem>5</ComboBoxItem>
<ComboBoxItem>6</ComboBoxItem>
<ComboBoxItem>7</ComboBoxItem>
<ComboBoxItem>8</ComboBoxItem>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)
它仍然是设置一个调整大小的处理程序Popup
.我将使用该函数在模板中进行搜索控制 FindChild<T>
.为了安全起见,我会做的事件ContentRendered
的Window
,要知道加载的所有元素:
private void Window_ContentRendered(object sender, EventArgs e)
{
// Find MainGrid in our ComboBox template
Grid MyMainGrid = FindChild<Grid>(ResizeComboBox, "MainGrid");
// Find Popup in Grid
Popup MyPopup = MyMainGrid.FindName("Popup") as Popup;
// Find Thumb in Popup
Thumb MyThumb = MyPopup.FindName("ResizeGripThumb") as Thumb;
// Set the handler
MyThumb.DragDelta += new DragDeltaEventHandler(MyThumb_DragDelta);
}
Run Code Online (Sandbox Code Playgroud)
上市FindChild<>
:
public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
{
if (parent == null)
{
return null;
}
T foundChild = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
T childType = child as T;
if (childType == null)
{
foundChild = FindChild<T>(child, childName);
if (foundChild != null) break;
}
else
if (!string.IsNullOrEmpty(childName))
{
var frameworkElement = child as FrameworkElement;
if (frameworkElement != null && frameworkElement.Name == childName)
{
foundChild = (T)child;
break;
}
else
{
foundChild = FindChild<T>(child, childName);
if (foundChild != null)
{
break;
}
}
}
else
{
foundChild = (T)child;
break;
}
}
return foundChild;
}
Run Code Online (Sandbox Code Playgroud)
处理程序列表MyThumb_DragDelta
:
private void MyThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
Thumb MyThumb = sender as Thumb;
Grid MyGrid = MyThumb.Parent as Grid;
// Set the new Width and Height fo Grid, Popup they will inherit
double yAdjust = MyGrid.Height + e.VerticalChange;
double xAdjust = MyGrid.Width + e.HorizontalChange;
// Set new Height and Width
if ((xAdjust >= 0) && (yAdjust >= 0))
{
MyGrid.Width = xAdjust;
MyGrid.Height = yAdjust;
}
}
Run Code Online (Sandbox Code Playgroud)
它是这样的:
Some notes:
要设置模板值,它们应该具有默认值,或者值将是NaN
,并且我们无法设置它们.我们在这里设置了这些参数:
<Grid Name="DropDown" Width="100" Height="100" SnapsToDevicePixels="True">
Run Code Online (Sandbox Code Playgroud)
可以在此处找到模板和代码的完整列表,因为它们的数量很大.风格不容易改变,因为它们是匆忙制作的,所以它们应该为自己做.
Part 2
至于存储输入的数据,它取决于您的目标.我想你可以这样做:
ObservableCollection
)来存储项目.which he was found
在某些来源中,将其保存到列表中.ComboBox
.只需设置属性并在下拉列表中显示输入字符(如我的示例所示).IsEditable
= "True"
IsTextSearchEnabled
= "True"
因此,您将有一个列表,其中添加了元素,可以向用户显示.
归档时间: |
|
查看次数: |
1073 次 |
最近记录: |