gpt4 book ai didi

wpf - 一个组合框,提供可调整大小的文件名完成列表和带有历史记录的下拉列表

转载 作者:行者123 更新时间:2023-12-03 20:51:29 25 4
gpt4 key购买 nike

我需要创建一个组合框

  • 提供可调整大小的文件名完成列表和
  • 保留以前输入的历史记录并在下拉列表中显示它们

  • 类似于 Windows 中的“运行”对话框。

    可调整大小的完成列表:

    file name completion

    下拉列表:

    drop-down list

    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;
    }
    }

    事件最好设置在 Thumb 控制(他也有事件 DragStarted DragCompleted )。

    一切都很好,但我们确实需要在 ComboBox 内部做.一种方法是使用 StyleTemplate .首先,添加 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>
    ...

    正常显示 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>

    现在,在这个阶段,我们展示了 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>

    现在,主要组件可以正常显示了。已声明 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>

    仍然需要设置一个处理程序来调整 Popup 的大小。 .我将使用函数 FindChild<T> 在模板中使其成为搜索控制。 .为了安全起见,我会在 ContentRenderedWindow ,要知道所有已加载的元素:
    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);
    }
    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;
    }

    处理程序列表 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;
    }
    }

    它是这样的:

    enter image description here
    Some notes:要设置模板值,它们应该有一个默认值,否则该值为 NaN ,我们不能设置它们。我们在这里设置了这些参数:
    <Grid Name="DropDown" Width="100" Height="100" SnapsToDevicePixels="True">      

    可以找到模板和代码的完整列表 here ,因为它们的体积很大。样式不能轻易改变,因为它们是匆忙制作的,所以应该为自己做。

    Part 2

    至于存储输入的数据,这取决于您的目标。我认为你可以这样做:
  • 创建一个列表(可能是 ObservableCollection )来存储项目。
  • 成功输入元素后,例如-which he was found在某些来源中,将其保存到您的列表中。
  • 将此列表绑定(bind)到 ComboBox .

  • 只需设置属性 IsEditable = "True" IsTextSearchEnabled = "True"在下拉列表中显示输入字符(如我的示例所示)。

    因此,您将有一个列表,其中添加了元素,可以向用户显示。

    关于wpf - 一个组合框,提供可调整大小的文件名完成列表和带有历史记录的下拉列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17602059/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com