简体   繁体   中英

Get content of textbox which is located in listView WPF

<ListView x:Name="listView2" HorizontalAlignment="Left" Height="215" Margin="348,10,0,0" VerticalAlignment="Top" Width="275">
    <ListView.View>
          <GridView>
               <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}"/>
               <GridViewColumn Header="Artikelnr" DisplayMemberBinding="{Binding Artikelnr}"/>
               <GridViewColumn Header="Bezeichnung" DisplayMemberBinding="{Binding Bezeichnung}"/>
               <GridViewColumn Header="Menge">
                   <GridViewColumn.CellTemplate>
                         <DataTemplate>
                              <TextBox x:Name="textBoxListView1" Width="80" Tag="{Binding Menge}"/>
                         </DataTemplate>
                   </GridViewColumn.CellTemplate>
               </GridViewColumn>    
           </GridView>
      </ListView.View>
 </ListView>

This is my ListView, which contains TextBoxes. So there are as many textboxes as rows. My question is how can I get the content of these textboxes?

I already tried this:

MyItem clMyItem = new MyItem();
clMyItem = (MyItem)listView2.Items.GetItemAt(zeile);

clArtikel.nId = Convert.ToInt32(clMyItem.Id);
clArtikel.cArtikelnr = clMyItem.Artikelnr;
clArtikel.cBezeichnung = clMyItem.Bezeichnung;
clArtikel.nMenge = clMyItem.Menge;

but for clMyItem.Menge it only returns a null value, probably because this code only gets the content of the textbox at a status directly after the textbox was created.

Try this:

int index = listView2.SelectedIndex;
if (index != -1)
{
    MyItem items = (MyItem)listView2.Items.GetItemAt(index);
    if (items != null)
    {
         var textBoxContent = items.Menge;
     }
}

The ItemsSource of a ListView is an ObservableCollection and I Binded here with Text Property

<DataTemplate>
   <TextBox x:Name="textBox" Width="80" Text="{Binding Menge}"/>
/DataTemplate>

make sure you implemented INotifyPropertyChanged in your MyItem Class to make sure your Menge property gets updated:

public class MyItem : INotifyPropertyChanged
{
    private string _menge = "";
    public String Menge
    {
        get { return _menge; }
        set
        {
            _menge = value;
            RaisePropertyChanged();
        }
    }

    public string Artikelnr { get; set; } = "";
    public String Bezeichnung { get; set; } = "";
    public String Id { get; set; } = "";

    #region Inotify
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged([CallerMemberName]string property = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
    #endregion
}

Output:

图片

You could also try somethin totally different.

Using the MVVM Pattern .

Create a Model first to hold all you data - lets call it "Bestellung":

public class Bestellung
{
    public int ID {get; set;}
    public int ArtikelNummer {get; set;}
    public string Bezeichnung {get; set;}
    public int Menge {get; set;}
}

Create a ViewModel like to bind your data to your view:

public class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Bestellung> Bestellungen {get; set;} = new ObservableCollection<Bestellung>();

    //Implement INotifyPropertyChanged here
}

What you need to do in your XAML is to set the ItemsSource to ItemsSource="{Binding Bestellungen}" and the DataContext so the view knows on where to look for the Bindings .

<ListView ItemsSouce="{Binding Bestellungen}">
<ListView.View>
      <GridView>
           <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}"/>
           <GridViewColumn Header="Artikelnr" DisplayMemberBinding="{Binding Artikelnr}"/>
           <GridViewColumn Header="Bezeichnung" DisplayMemberBinding="{Binding Bezeichnung}"/>
           <GridViewColumn Header="Menge">
               <GridViewColumn.CellTemplate>
                     <DataTemplate>
                          <TextBox Width="80" Text="{Binding Menge}"/>
                     </DataTemplate>
               </GridViewColumn.CellTemplate>
           </GridViewColumn>    
       </GridView>
  </ListView.View>

Here you bind your TextBox containing "Menge" directrly to the property Menge of each item in your ListView.

Also you could get rid of all those x:Name s because you won't need most of them anymore.

You could do this in YourWindow.xaml.cs

//Code-Behind of your Window
public class YourWindow : Window
{
    public YourWindow()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }
}

The good thing about this is that you can separate your logic and your view.


That means : You won't access your textbox anymore - because you don't care if it's a TextBox , TextBlock or sth. else. Your logic does not need to know what's in your view.

To access and change any property of one of your items you could just do this:

//Add 3 pcs to the order
Bestellungen.First(bestellung => bestellung.Id == "010101").Menge += 3;

or

//Delete an order
Bestellungen.Remove(Bestellungen[2]);

The ObservableCollection observes your model and will notify the UI once something changed. Your new value should be instantly visible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM