【问题标题】:Add items to comboBox in WPF将项目添加到 WPF 中的组合框
【发布时间】:2012-08-09 06:55:46
【问题描述】:

当我在 WPF 窗口中添加了一个组合框后,如何向组合框添加项目? Int 设计或 NameOfWindow.xaml.cs 文件中的 XAML 代码?

【问题讨论】:

  • WPF 有一个很棒的功能。它被称为“数据绑定”。从 WPF 开始 this 应该可以帮助你。
  • ahem.. WinForms 也有数据绑定 :)
  • 我没有提到相反的情况。我刚刚说过 WPF 数据绑定是一个很棒的功能 :)

标签: c# wpf


【解决方案1】:

案例 1 - 您没有数据源:

您可以使用静态值填充ComboBox,如下所示 -

  1. 来自 XAML:
<ComboBox Height="23" Name="comboBox1" Width="120">
    <ComboBoxItem Content="Alice"/>
    <ComboBoxItem Content="Bob"/>
    <ComboBoxItem Content="Charlie"/>
</ComboBox>
  1. 来自 CodeBehind - 1:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    comboBox1.Items.Add("Alice");
    comboBox1.Items.Add("Bob");
    comboBox1.Items.Add("Charlie");
}
  1. 来自 CodeBehind - 2:
// insert item at specified index of populated ComboBox
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    comboBox1.Items.Insert(2, "Alice");
    comboBox1.Items.Insert(5, "Bob");
    comboBox1.Items.Insert(8, "Charlie");
}

案例 2 - 您有一个数据源,并且项目永远不会更改:

您可以使用数据源来填充ComboBox任何 IEnumerable 类型可以用作数据源。你可以-

  1. XAML 中的ItemsSource 属性绑定到数据源,例如-
<!-- MyDataSource is an IEnumerable type property in ViewModel -->
<ComboBox Height="23" Width="120" ItemsSource="{Binding MyDataSource}" />
  1. 将数据源分配给代码隐藏中的ItemsSource 属性,例如 -
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    comboBox1.ItemsSource = new List<string> { "Alice", "Bob", "Charlie" };
}

案例 3 - 您有一个数据源,项目可能会更改

  1. 应该使用ObservableCollection&lt;T&gt;作为数据源
  2. 应该XAML 中的ItemsSource 属性绑定到数据源(如上所示)
  3. 可以将数据源分配给代码隐藏中的ItemsSource 属性(如上所示)

使用ObservableCollection&lt;T&gt; 可确保无论何时将项目添加到数据源或从数据源中删除,更改都会立即反映在 UI 上。如何填充 ObservableCollection&lt;T&gt; 取决于您。

【讨论】:

    【解决方案2】:

    最好构建ObservableCollection 并利用它

    public ObservableCollection<string> list = new ObservableCollection<string>();
    list.Add("a");
    list.Add("b");
    list.Add("c");
    this.cbx.ItemsSource = list;
    

    cbx 是组合框名称

    另请阅读:Difference between List, ObservableCollection and INotifyPropertyChanged

    【讨论】:

      【解决方案3】:

      使用这个

      string[] str = new string[] {"Foo", "Bar"};
      
      myComboBox.ItemsSource = str;
      myComboBox.SelectedIndex = 0;
      

      foreach (string s in str)
          myComboBox.Items.Add(s);
      
      myComboBox.SelectedIndex = 0;      
      

      【讨论】:

      • 很好,它运行良好!但是,如果我想要组合框的名称或标题,例如“您的选项:”,那么我想我只是将它添加到数组中的第一个,但是当进行选择时,我会检查索引 0 是否未被激活!?还是有更好的方法?
      • 不,我得到了两次“你的选择”!?它在“按钮”上,但它也在我点击组合框时下拉的列表中!
      • 有没有办法解决这个问题?我想要按钮上的名称,当我按下按钮时,我想要下拉项目,而不是按钮的名称? Preciate 如果这可以做到!
      【解决方案4】:

      您可以从 XAML 或 .cs 填充它。用数据填充控件的方法很少。您最好阅读有关 WPF 技术的更多信息,它允许根据您的需要以多种方式做很多事情。根据您的项目需求选择方法更为重要。你可以开始here。这是一篇关于创建组合框并用一些数据填充它的简单文章。

      【讨论】:

        【解决方案5】:

        有很多方法可以执行此任务。这是一个简单的:

        <Window x:Class="WPF_Demo1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Name="TestWindow"
            Title="MainWindow" Height="500" Width="773">
        
        <DockPanel LastChildFill="False">
            <StackPanel DockPanel.Dock="Top" Background="Red" Margin="2">
                <StackPanel Orientation="Horizontal" x:Name="spTopNav">
                    <ComboBox x:Name="cboBox1" MinWidth="120"> <!-- Notice we have used x:Name to identify the object that we want to operate upon.-->
                    <!--
                        <ComboBoxItem Content="X"/>
                        <ComboBoxItem Content="Y"/>
                        <ComboBoxItem Content="Z"/>
                    -->
                    </ComboBox>
                </StackPanel>
            </StackPanel>
            <StackPanel DockPanel.Dock="Bottom" Background="Orange" Margin="2">
                <StackPanel Orientation="Horizontal" x:Name="spBottomNav">
                </StackPanel>
                <TextBlock Height="30" Foreground="White">Left Docked StackPanel 2</TextBlock>
            </StackPanel>
            <StackPanel MinWidth="200" DockPanel.Dock="Left" Background="Teal" Margin="2" x:Name="StackPanelLeft">
                <TextBlock  Foreground="White">Bottom Docked StackPanel Left</TextBlock>
        
            </StackPanel>
            <StackPanel DockPanel.Dock="Right" Background="Yellow" MinWidth="150" Margin="2" x:Name="StackPanelRight"></StackPanel>
            <Button Content="Button" Height="410" VerticalAlignment="Top" Width="75" x:Name="myButton" Click="myButton_Click"/>
        
        
        </DockPanel>
        
        </Window>      
        

        接下来,我们有 C# 代码:

            private void myButton_Click(object sender, RoutedEventArgs e)
            {
                ComboBoxItem cboBoxItem = new ComboBoxItem(); // Create example instance of our desired type.
                Type type1 = cboBoxItem.GetType();
                object cboBoxItemInstance = Activator.CreateInstance(type1); // Construct an instance of that type.
                for (int i = 0; i < 12; i++)
                {
                    string newName = "stringExample" + i.ToString();
                   // Generate the objects from our list of strings.
                    ComboBoxItem item = this.CreateComboBoxItem((ComboBoxItem)cboBoxItemInstance, "nameExample_" + newName, newName);
                    cboBox1.Items.Add(item); // Add each newly constructed item to our NAMED combobox.
                }
            }
            private ComboBoxItem CreateComboBoxItem(ComboBoxItem myCbo, string content, string name)
            {
                Type type1 = myCbo.GetType();
                ComboBoxItem instance = (ComboBoxItem)Activator.CreateInstance(type1);
                // Here, we're using reflection to get and set the properties of the type.
                PropertyInfo Content = instance.GetType().GetProperty("Content", BindingFlags.Public | BindingFlags.Instance);
                PropertyInfo Name = instance.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);
                this.SetProperty<ComboBoxItem, String>(Content, instance, content);
                this.SetProperty<ComboBoxItem, String>(Name, instance, name);
        
                return instance;
                //PropertyInfo prop = type.GetProperties(rb1);
            }
        

        注意:这是使用反射。 如果您想了解更多关于反射的基础知识以及为什么要使用它,这是一篇很棒的介绍性文章:

        如果您想了解更多关于如何具体使用 WPF 的反射,这里有一些资源:

        如果你想大量加速反射的性能,最好使用IL来做到这一点,像这样:

        【讨论】:

          【解决方案6】:

          我认为comboBox1.Items.Add("X"); 会将string 添加到ComboBox,而不是ComboBoxItem

          正确的解决方案是

          ComboBoxItem item = new ComboBoxItem();
          item.Content = "A";
          comboBox1.Items.Add(item);
          

          【讨论】:

            【解决方案7】:

            使用 OleDBConnection -> 连接到 Oracle

            OleDbConnection con = new OleDbConnection();
                        con.ConnectionString = "Provider=MSDAORA;Data Source=oracle;Persist Security Info=True;User ID=system;Password=**********;Unicode=True";
            
                        OleDbCommand comd1 = new OleDbCommand("select name from table", con);
                        OleDbDataReader DR = comd1.ExecuteReader();
                        while (DR.Read())
                        {
                            comboBox_delete.Items.Add(DR[0]);
                        }
                        con.Close();
            

            就是这样:)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-02-08
              • 1970-01-01
              • 2016-01-19
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多