|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Services
Chapters
Feature Zones
|
BackgroundHaving just read Sacha Barber's article WPF: A Beginners Guide - Part 5 of N, I wondered how to get IntroductionSacha's article uses a very simple collection of I kept the UI down to a very simple The DataBase TableCreated by adding a Service Based Database to the Solution using Add Item.. in Solution Explorer and then using Database Explorer, I added the new table The LINQ-SQL ClassUsing Solution Explorer add Item.. adding a LINQ-SQL class is simple. A designer pane opens onto which I drag the The ObservableCollectionThe LINQ-SQL public class ObservablePeople: ObservableCollection<People>
{
public ObservablePeople(DataClasses1DataContext dataDc)
{
//Open class view to find out what Properties the wizard
//had created in the DataClasses1DataContext class, otherwise
//I wouldn't have known about Peoples
foreach ( People thisPerson in dataDc.Peoples)
{
this.Add(thisPerson);
}
}
}
The WPF C# Code BehindI gave the WPF window some properties to access and use the database and the collection of Adding New Records to the DatabaseThe click handler for the Add button takes the name entered in Editing Selected PeopleThis is accomplished completely in XAML, Text="{Binding ElementName=listBox1, Path=SelectedItem.PersonName,
UpdateSourceTrigger=PropertyChanged}"
... which binds to the Committing the Changes to DatabaseAll the changes made have had an effect on the objects in the The Window Codeusing 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;
namespace WpfDbLinqBind1
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private static DataClasses1DataContext _dataDC = new DataClasses1DataContext();
// class created by wizard when adding a LINQ to SQL item in solution explorer
// and dragging the People table from the data explorer - NB: if you forget to
// set a primary key column in the table before doing that the wizard doesn't
// set INotifyPropertyChanged to the class and you can't insert
// into the database, and binding goes wrong
private ObservablePeople _knownPeople;
public Window1()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//populate the observable collection of people from the Database
_knownPeople = new ObservablePeople(_dataDC);
this.listBox1.ItemsSource = _knownPeople;
}
private void add_Click(object sender, RoutedEventArgs e)
{
if (textBox1.Text.Length > 0 )
{
People newPerson = new People();
newPerson.PersonName = textBox1.Text;
//inserts to DB people table, isn't committed yet, and it is
//not visible
_dataDC.Peoples.InsertOnSubmit(newPerson);
//adds to _knownPeople collection, observable class notifies
//listbox and makes visible
_knownPeople.Add(newPerson);
// what I really wanted was to see _knownPeople updated automatically
// when the row was inserted to the datacontext, and vice-versa,
// but that's not happening. binding works on the new record because
// it's literally the same newPerson object in both collections,
// not just a copy.
textBox1.Text = "";
}
}
private void commit_Click(object sender, RoutedEventArgs e)
{
//commit the changes to the database for persistence
_dataDC.SubmitChanges();
// when running in debug mode in VS2008 any rebuild resets the DB back
// to the starting test data we entered in database explorer. Exit the
// App and re-start debugging without changing any code and you see the
// changes are persistent in the DB, and are lost as soon as you re-compile.
// obviously not a problem in the release build. Remember to use
// database explorer to remove the test data before the final
// build unless you want it released
}
private void Delete_Click(object sender, RoutedEventArgs e)
{
if (listBox1.SelectedItem != null)
{
// this works because the object in the listbox source collection
// i.e. _knownPeople is literally the same object held in
// the _dataDc ,so _dataDC knows which record it is
_dataDC.Peoples.DeleteOnSubmit( (People)listBox1.SelectedItem); // mark
// for deletion
_knownPeople.Remove((People)listBox1.SelectedItem);
}
}
}
}
XAML Notes and QueriesThe <DataTemplate x:Key="pName">
<!-- needed because the record has 2 fields,
primary key PersonId and PersonName, want to display PersonName
-->
<TextBlock Text="{Binding Path=PersonName}"/>
</DataTemplate>
... and the listbox sets the... ItemTemplate="{StaticResource pName}"
... to use it.
It is convenient that the edit textbox can use the dotted syntax Points of Interest
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||