如何从代码隐藏中访问ListBox动态创建项的属性?

时间:2009-12-25 20:24:22

标签: wpf listbox

XAML:

<Window x:Class="WpfApp_ListBoxTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
  <ListBox Name="lb" Margin="0,0,0,70"></ListBox>
  <Button Height="23" HorizontalAlignment="Left" Margin="12,0,0,41" Name="btnAdd" VerticalAlignment="Bottom" Content="Add item" Width="75" Click="btnAdd_Click"></Button>
  <TextBox Height="23" Margin="93,0,12,41" Name="txtInput" VerticalAlignment="Bottom" />
  <Button Height="23" HorizontalAlignment="Left" Margin="12,0,0,12" Name="btnGet" VerticalAlignment="Bottom" Content="Get value" Width="75" Click="btnGet_Click"></Button>
  <TextBox Height="23" Margin="93,0,12,12" Name="txtReturn" VerticalAlignment="Bottom" IsReadOnly="True" />
 </Grid>
</Window>

Csharp的:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;

namespace WpfApp_ListBoxTest
{
 /// <summary>
 /// Interaction logic for Window1.xaml
 /// </summary>
 public partial class Window1 : Window
 {
  public Window1()
  {
   InitializeComponent();
  }

  private void btnAdd_Click(object sender, RoutedEventArgs e)
  {
   TextBox txt = new TextBox();
   txt.Width = 200;
   txt.Text = txtInput.Text;
   lb.Items.Add(txt);
  }

  private void btnGet_Click(object sender, RoutedEventArgs e)
  {
   // What do I need to write here to get the value of the Text property of the selected TextBox?

  }
 }
}

截图:(抱歉,我不允许直接发布图片) http://i825.photobucket.com/albums/zz180/mGlushed/get_listbox_item_property.png

(在上图中,我想点击“获取值”按钮时得到值“b”。)

我想知道是否有一种简单的方法可以实现这一点。

我是WPF的新手,所以我只知道这么做很长一段路,即:创建一个数组。每次创建新的TextBox时,将其添加到数组中。然后通过数组访问TextBox'es。但我认为这听起来不是很理想。

4 个答案:

答案 0 :(得分:2)

做你想做的事的'WPF方式'是使用数据绑定:

  1. 使用名为Text的字符串属性定义一个类。
  2. 创建该类的集合。
  3. 将列表框ItemsSource绑定到集合。
  4. 创建一个DataTemplate,显示一个TextBox,其Text属性使用{Binding Path = Text}进行绑定。
  5. 在btnAdd_Click中添加一个项目到集合(不是直接添加到ListBox)
  6. 在btnGet_Click中,您可以通过将ListBox.SelectedItem强制转换为您的类并获取其Text属性来获取输入的文本。
  7. 示例:

    简单的课程:

    public class VMObject
    {
        public VMObject(string text)
        {
            Text = text;
        }
    
        public string Text { get; set; }
    }
    

    窗口代码隐藏:

    public partial class Window1 : Window
    {
        public ObservableCollection<VMObject> VM { get; set; }
    
        public Window1()
        {
            VM = new ObservableCollection<VMObject>();
            InitializeComponent();
        }
    
        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            VM.Add(new VMObject(txtInput.Text));
        }
    
        private void btnGet_Click(object sender, RoutedEventArgs e)
        {
            if (lb.SelectedItem == null)
                MessageBox.Show("No item is selected!");
            txtReturn.Text = ((VMObject)lb.SelectedItem).Text;
        }
    }
    

    XAML:

    <Window x:Class="lbtest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Name="Window"
        Title="Window1" Height="300" Width="300">
        <Window.Resources>
            <DataTemplate x:Key="TextBoxTemplate">
                <TextBox Text="{Binding Path=Text}"/>
            </DataTemplate>
        </Window.Resources>
        <Grid>
            <ListBox Name="lb" Margin="0,0,0,70"
                     ItemsSource="{Binding ElementName=Window, Path=VM}"
                     ItemTemplate="{StaticResource TextBoxTemplate}" />
            <Button Height="23" HorizontalAlignment="Left" Margin="12,0,0,41"
                    Name="btnAdd" VerticalAlignment="Bottom"
                    Content="Add item" Width="75" Click="btnAdd_Click" />
            <TextBox Height="23" Margin="93,0,12,41"
                     Name="txtInput" VerticalAlignment="Bottom" />
            <Button Height="23" HorizontalAlignment="Left" Margin="12,0,0,12"
                    Name="btnGet" VerticalAlignment="Bottom"
                    Content="Get value" Width="75" Click="btnGet_Click" />
            <TextBox Height="23" Margin="93,0,12,12"
                     Name="txtReturn" VerticalAlignment="Bottom" IsReadOnly="True" />
        </Grid>
    </Window>
    

答案 1 :(得分:1)

表示复选框项目:

private void chk_Checked(object sender, RoutedEventArgs e)
{
    CheckBox chk = (CheckBox)sender;
    MessageBox.Show(chk.Content.ToString()); 
}

答案 2 :(得分:0)

不需要TextBox:s。 ListBox句柄很好。

    private void btnAdd_Click(object sender, RoutedEventArgs e)
    {
        // No need to create TextBox, ListBox handle strings fine.
        lb.Items.Add(txtInput.Text);
    }

    private void btnGet_Click(object sender, RoutedEventArgs e)
    {
        // No selection, but button has been pressed.
        if(lb.SelectedItem == -1)
            return;
        // Get selected item.
        txtReturn.Text = (string)lb.SelectedItem;

        /* If you change ListBox selection mode to multiple
         * you can get all selected items by using foreach loop.
        foreach (Object selected in lb.SelectedItems)
        {
            txtReturn.Text +=  (string) selected;
        }
         */
    }

答案 3 :(得分:0)

如果您只想获取所选TextBox的Text属性(允许ListBox处于单选模式),那么它非常简单:

private void btnGet_Click(object sender, RoutedEventArgs e)
{
    if(lb.SelectedItem != -1)
    {
        TextBox selectedTextBox = (TextBox)lb.SelectedItem;
        txtReturn.Text = selectedTextBox.Text;
    }
}

但是如果你想实现漂亮的WPF方式,你应该遵循Aviad P.解决方案,我的解决方案也做得很好。

问候。


编辑:如果没有真正需要TextBox功能,但只有一个字符串容器,那么请遵循Tuukka的解决方案。

相关问题