Как получить доступ к свойствам динамически создаваемых элементов ListBox из выделенного кода? - PullRequest
2 голосов
/ 25 декабря 2009

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'ам через массив. Но это звучит не очень оптимально, я думаю.

Ответы [ 4 ]

2 голосов
/ 25 декабря 2009

«Путь WPF» в том, что вы хотите, это использовать привязку данных:

  1. Определить класс со строковым свойством с именем Text.
  2. Создать коллекцию этого класса.
  3. Свяжите свой список ListSource с коллекцией.
  4. Создайте DataTemplate, который показывает TextBox с привязанным свойством Text, используя {Binding Path = Text}.
  5. In btnAdd_Clickдобавить элемент в коллекцию (не напрямую в ListBox)
  6. В btnGet_Click вы можете получить введенный текст, приведя ListBox.SelectedItem к вашему классу и получив его свойство Text.

Пример:

Простой класс:

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 голос
/ 01 февраля 2012

для пункта флажка:

private void chk_Checked(object sender, RoutedEventArgs e)
{
    CheckBox chk = (CheckBox)sender;
    MessageBox.Show(chk.Content.ToString()); 
}
0 голосов
/ 26 декабря 2009

Если вы просто хотите получить свойство Text выбранного TextBox (если ваш 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.

0 голосов
/ 25 декабря 2009

Нет необходимости в 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;
        }
         */
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...