【问题标题】:WPF Multi-Column ComboboxWPF 多列组合框
【发布时间】:2020-08-09 17:03:48
【问题描述】:

我知道有人问过这个问题,并且我查看了很多结果,但我发现的结果似乎并不完全有效,或者它们给我带来了问题。

我想要的是一个我可以输入的组合框,它将开始自动完成并根据单个列缩小范围。例如,如果我有名字和姓氏,我会输​​入,姓氏会缩小。

在下面的示例中,当我在组合框中选择一个值时,我得到“System.Data.DataRowView”。 我已经使用选择更改事件进行了测试,只是为了检查,我什至无法为组合设置文本,但如果我可以从数据表中返回正确的值。

如果对一个好的综合资源有任何建议,比如网站、教程、视频、在线课程、书籍,我将不胜感激。

  1. 搜索组合框和自动更新项目
  2. 显示选定项目的特定字段

资源 XAML:

 <Style x:Key="txtStyle" TargetType="{x:Type TextBlock}">
            <Setter Property="TextAlignment" Value="Left"></Setter>
            <Setter Property="FontSize" Value="14"></Setter>
            <Setter Property="HorizontalAlignment" Value="Left"></Setter>
        </Style>

 <DataTemplate x:Key="comboKEY">
            <Grid Height="25" Width="300" ShowGridLines="false">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0"></ColumnDefinition>
                    <ColumnDefinition Width="200"></ColumnDefinition>
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0"  Text="{Binding Path='id'}"
                    Style="{StaticResource txtStyle}"></TextBlock>
                <TextBlock Grid.Column="1"  Text="{Binding Path='site_name'}"
                    Style="{StaticResource txtStyle}"
                           TextWrapping="Wrap"></TextBlock>
            </Grid>
        </DataTemplate>

XAML 组合框

<WrapPanel Orientation="Horizontal" Canvas.Left="10" Canvas.Top="90">
                <ComboBox IsEditable="True"
                  Width="200"
                  Height="25"
                  IsTextSearchEnabled="False"
                  x:Name="cboName"
                  ItemTemplate="{StaticResource comboKEY
                  ItemsSource="{Binding}" SelectionChanged="cboName_SelectionChanged">
                </ComboBox>
            </WrapPanel>

代码隐藏

 private void cboName_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            cboName.Text = dt.Rows[cboName.SelectedIndex]["dt_field"].ToString();
           
            test1.Content = dt[cboName.SelectedIndex]["dt_field"].ToString();
        }

【问题讨论】:

  • 我不清楚您要做什么。您想根据输入到 ComboBox 文本字段中的文本过滤 ComboBox 中建议的项目吗?那么多列部分呢? ComboBox 绑定到什么?
  • 它绑定到一个数据表。所以它充满了物品让我们说ID |名字 | LASTNAME,当我输入它时,可以说 LASTNAME 过滤结果。在我的示例中,它返回一行,但如何告诉它显示特定字段。

标签: c# wpf combobox


【解决方案1】:

当您想要过滤或排序DataTable 时,您应该创建一个DataView 并绑定到它。然后使用分配给DataView.RowFilterfilter expression 来动态过滤表。

以下示例显示如何通过处理由ComboBox 的可编辑TextBox 引发的TextBox.TextChanged 来根据文本输入进行过滤。
要过滤的列也是动态的。

由于ComboBox.IsEditable 设置为True,选择框的ContenPresenter 将替换为TextBox。这意味着您只能显示文本。默认情况下,ComboBox 将调用object.ToString()。如果像DataRowView 这样的项目没有提供可用的覆盖,您可以设置ComboBox.DisplayMemberPath。设置此属性不允许设置ComboBox.ItemTemplate。如果您仍想布局下拉项,则必须覆盖 ComboBox.ItemContainerStyle

MainWindow.xaml.cs

partial class MainWindow : Window
{
  // This property should be a DependencyProperty
  public DataView DataTableView { get; set; }

  // This property should be a DependencyProperty and have a property changed callback to update the DataTableView filter registered
  public string FilteredColumnName { get; set; }

  public MainWindow()
  { 
    InitializeComponent();
    this.DataContext = this;

    var dataTable = new DataTable();
   
    // TODO::Populate DataTable.
    // Assume table has a column 'LastName'

    this.DataTableView = dataTable.DefaultView;

    // Filter based on column 'LastName'
    this.FilteredColumnName = "LastName";
  }

  private void FilterDataTable_OnTextInput(object sender, TextChangedEventArgs textChangedEventArgs)
  {
    var comboBox = sender as ComboBox;
    var dataview = comboBox.ItemsSource as DataView;

    // Filter based on column 'LastName', 
    // where the value starts with the entered text: '<columnName> LIKE '<textInput>*'
    dataview.RowFilter = $"{this.FilteredColumnName} LIKE '{(textChangedEventArgs.OriginalSource as TextBox).Text}*'";
  }
}

MainWindow.xaml

<Window>
  <ComboBox ItemsSource="{Binding DataTableView}"
            DisplayMemberPath="LastName"
            SelectedValuePath="LastName"
            IsEditable="True" 
            StaysOpenOnEdit="True"
            TextBox.TextChanged="FilterDataTable_OnTextInput">
    <ComboBox.ItemContainerStyle>
      <Style TargetType="{x:Type ComboBoxItem}">
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
              <Border BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}"
                      Background="{TemplateBinding Background}">
                <StackPanel Orientation="Horizontal">
                  <TextBlock Text="{Binding Name}" />
                  <TextBlock Text="{Binding LastName}" />
                </StackPanel>
              </Border>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
    </ComboBox.ItemContainerStyle>
  </ComboBox>
</Window>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-30
    • 2016-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多