简体   繁体   中英

ListBox doesn't refresh?

i have an issue on Visual Studio(wpf) with the listbox. If i want to insert or delete some data from the database, then they are working,but the listbox will just be refreshed if i'm clicking the menuitem for once. I think this is due to the load method, but why isn't it refreshing the data?

This is my XAML-Code:

  <UserControl x:Class="WpfApplication1.AutorenBearbeiten"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApplication1"
             mc:Ignorable="d" 
             d:DesignHeight="400" d:DesignWidth="300" Loaded="UserControl_Loaded">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="28*" />
            <ColumnDefinition Width="36*" />
        </Grid.ColumnDefinitions>
        <TextBlock Text="Medien" Grid.ColumnSpan="2" 
                   FontSize="16" />





        <ListBox x:Name="box" Grid.Row="1">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=at_nachname}" />



                </DataTemplate>

            </ListBox.ItemTemplate>
        </ListBox>

        <StackPanel DataContext="{Binding ElementName=box,Path=SelectedItem}" Grid.Column="1" Grid.Row="1" >
            <TextBlock Text="Autoren_id" />
            <TextBox  Text="{Binding Path=at_id}"  MaxLength="5"/>
            <TextBlock Text="Vorname"  />
            <TextBox   Text="{Binding Path=at_vorname}"   MaxLength="30"/>
            <TextBlock Text="Nachname" />
            <TextBox  Text="{Binding Path=at_nachname}"  MaxLength="30"/>
            <TextBlock Text="Geburtsdatum"  />
            <TextBox   MaxLength="30"  Text="{Binding Path=at_gebDatum, StringFormat=dd.MM.yyyy}" />
            <Button Name="speichern" Height="23" Margin="4" Click="speichern_Click">Änderungen speichern</Button>
            <Button Name="loeschen" Height="23" Margin="4" Click="loeschen_Click">Löschen</Button>

            <StackPanel DataContext="{Binding ElementName=box}" Grid.Column="1" Grid.Row="1" >
                <TextBlock Text="Autoren_id" />
                <TextBox x:Name="id"  MaxLength="5"/>
                <TextBlock Text="Vorname" />
                <TextBox  x:Name="vorname"   MaxLength="30"/>
                <TextBlock Text="Nachname" />
                <TextBox x:Name="nachname"   MaxLength="30"/>
                <TextBlock Text="Geburtsdatum" />
                <TextBox  x:Name="datum" MaxLength="30"/>
                <Button x:Name="neubutton"  Height="23" Margin="4" Click="neu_Click">Neu</Button>
                <TextBlock Name="submitfehler" FontWeight="Bold" Foreground="Red" />
            </StackPanel>

        </StackPanel>

    </Grid>
</UserControl>

And this is the xaml.cs file :

    using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for AutorenBearbeiten.xaml
    /// </summary>
    public partial class AutorenBearbeiten : UserControl
    {
        libraryEntities6 db = new libraryEntities6();
        public AutorenBearbeiten()
        {
            InitializeComponent();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            var erg = db.a_autor;

            erg.Load();
            box.ItemsSource = erg.Local.OrderBy(m => m.at_id);

            box.ItemsSource =
               (from m in db.a_autor
                orderby m.at_id
                select m).ToList();


    }

        private void speichern_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                db.SaveChanges();
            }
            catch(Exception e1)
            {
                submitfehler.Text = e1.Message;
            }
        }

        private void loeschen_Click(object sender, RoutedEventArgs e)
        {

            a_autor am = (a_autor)box.SelectedItem;
            if (am != null)
            {

                db.a_autor.Remove(am);
                db.SaveChanges();
                box.Items.Refresh();
            }

        }

        private void neu_Click(object sender, RoutedEventArgs e)
        {


            a_autor autor = new a_autor();
            autor.at_id = id.Text;
            autor.at_vorname = vorname.Text;
            autor.at_nachname = nachname.Text;
            autor.at_gebDatum = Convert.ToDateTime(datum.Text);


            //s1.s_k_klasse = liklassen.SelectedValue.ToString() setzt die Klasse via foreign key
            //db.schuelers.AddObject(s1);


            db.a_autor.Add(autor);
            box.Items.Refresh();



            /*
            ((klassen))liklassen.SelectedItem).schuelers.Add(s1); //setzt die klasse durch zuweisen zum nav.Property
            lischueler.Items.Refresh(); //nötig weil das navigational seit ER 5 nicht observable ist
            */

        }
    }
}

A Picture from the window is below:

Window

You should use MVVM pattern instead of code behind and use property changes. First result in Google:

https://www.codeproject.com/Articles/819294/WPF-MVVM-step-by-step-Basics-to-Advance-Level

I hope it helps you.

Juan

You can create an ObservableCollection instead of binding to the List . ObservableCollection implements INotifyPropertyChanged so it can send a notification whenever something is changed in the container.

Also, I would suggest you to try

public void RefreshListBox()
{
     box.ItemsSource =
               (from m in db.a_autor
                orderby m.at_id
                select m).ToList();

}

and call this after db.SaveChanges()

There is no magic connection between the ListBox and the database so when you are calling the Add or Remove method of the DbContext the ListBox won't be affected.

What you should do is to set the ItemsSource property of the ListBox to an ObservableCollection<a_autor> and then call the Add/Remove method of this one besides calling the Add/Remove method of the DbContext:

System.Collections.ObjectModel.ObservableCollection<a_autor> _sourceCollection;
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    var erg = db.a_autor;
    erg.Load();

    _sourceCollection = new System.Collections.ObjectModel.ObservableCollection<a_autor>((from m in db.a_autor
                                                                                          orderby m.at_id
                                                                                          select m).ToList());
    box.ItemsSource = _sourceCollection;
}

private void loeschen_Click(object sender, RoutedEventArgs e)
{
    a_autor am = (a_autor)box.SelectedItem;
    if (am != null)
    {
        _sourceCollection.Remove(am);
        db.a_autor.Remove(am);
        db.SaveChanges();
        box.Items.Refresh();
    }

}

private void neu_Click(object sender, RoutedEventArgs e)
{
    a_autor autor = new a_autor();
    autor.at_id = id.Text;
    autor.at_vorname = vorname.Text;
    autor.at_nachname = nachname.Text;
    autor.at_gebDatum = Convert.ToDateTime(datum.Text);

    _sourceCollection.Add(autor);
    db.a_autor.Add(autor);
    box.Items.Refresh();
}

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