rozwiązanie dla WPF
Part 1
Zasada, można użyć stylów i szablonów do realizacji Twojego pytania. W ComboBox
wynik jest podany w Popup
, ale domyślnie nie obsługuje zmiany rozmiaru. Dodaj zmianę rozmiaru nie jest trudne, jeśli używasz zdarzenia DragDelta
. Przykład:
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;
}
}
Impreza jest lepiej ustawiony na kontrolę Thumb
(Ma również wydarzenia DragStarted
, DragCompleted
).
Wszystko jest bardzo dobrze, ale musimy zrobić wewnątrz ComboBox
. Jednym ze sposobów jest użycie Style
i Template
. Aby rozpocząć, dodaj Thumb
w stylu ComboBox
więc wydaje się w rozszerzonej listy:
...
<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>
...
do normalnego wyświetlania Thumb
, dodać do tego stylu z 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>
Teraz, na tym etapie, pokazaliśmy ResizeGrip
w rozwiniętej liście. Ale domyślna ScrollBar
, a następnie zamyka go swoją obecnością, dlatego też definiuje styl dla ScrollBar
. Spowoduje to zmianę marginesu VerticalThumb
, a więc:
...
<!-- 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>
Teraz jest normalny wyświetlacz z głównych składników.Deklarowana ComboBox
w 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>
Pozostaje ustawić obsługi do zmiany rozmiaru Popup
. Zrobię kontrolę wyszukiwania w szablonie za pomocą funkcji FindChild<T>
. Pewności, zrobię to w przypadku ContentRendered
z Window
, aby wiedzieć, że wszystkie elementy ładowane:
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);
}
Notowania 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;
}
Notowania obsługi 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;
}
}
Tak:
Some notes:
Aby ustawić wartości szablonów, powinny one mieć wartość domyślną lub wartość będzie wynosić NaN
, a my nie możemy ich ustawić. Mamy te parametry są ustawione tutaj:
<Grid Name="DropDown" Width="100" Height="100" SnapsToDevicePixels="True">
Pełną listę szablonów i kodu można znaleźć here, ponieważ są one w dużej objętości. Style nie mogą być łatwo zmienione, ponieważ zostały wykonane w pośpiechu, więc powinny zrobić dla siebie.
Part 2
chodzi o zapamiętanie wprowadzonych danych, to zależy od Twoich celów. Myślę, że możesz zrobić coś takiego:
- Utwórz listę (może być
ObservableCollection
) do przechowywania przedmiotów.
- Po pomyślnym wprowadzeniu elementu, na przykład -
which he was found
w niektórych źródłach, zapisz go na liście.
- Wiązanie tej listy w
ComboBox
.
Wystarczy ustawić właściwości IsEditable
= "True"
i IsTextSearchEnabled
= "True"
aby wyświetlić znak wejściowy z listy rozwijanej (jak w moim przykładzie).
W ten sposób otrzymasz listę, w której dodawane są elementy, które mogą być pokazywane użytkownikowi.
lista budowy jest skalowalny tylko Windows 8. – Vladimir