Text="{Binding
Path=Attribute[id].Value}"
Text="{Binding Path=Value}"
<Window.Resources> tag with both
of these definitions is given below:
<Window.Resources>
<!-- Books provider and inline
XML data -->
<ObjectDataProvider x:Key="LoadedBooks"
ObjectType="{x:Type xlinq:XElement}"
MethodName="Parse">
<ObjectDataProvider.MethodParameters>
<system:String
xml:space="preserve">
<![CDATA[
<books
xmlns="http://www.mybooks.com">
<book
id="1">Seven ways to Success</book>
<book
id="2">My Experiments with Truth</book>
<book
id="3">Leadership Skills</book>
<book
id="4">India and Politics Today</book>
</books>
]]>
</system:String>
<xlinq:LoadOptions>PreserveWhitespace</xlinq:LoadOptions>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<!-- Template for use in Books
List listbox. -->
<DataTemplate
x:Key="BookTemplate">
<StackPanel
Orientation="Horizontal">
<TextBlock Margin="3"
Text="{Binding Path=Attribute[id].Value}"/>
<TextBlock Margin="3"
Text="-"/>
<TextBlock Margin="3"
Text="{Binding Path=Value}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
Once the DataTemplate is ready as a
data resource, Data Binding can be performed with the WPF controls in the User
Interface.
In the <StackPanel> tag, the
DataContext property is set to the “LoadedBooks” data provider.
DataContext="{Binding
Source={StaticResource LoadedBooks}}
This makes it possible for the
TextBlock named tbRawXml to display the raw XML by binding to this data
provider's Xml property:
Text="{Binding Path=Xml}"
The ListBox in the Book List UI
section, sets the template for its display items to the “BookTemplate“
resource and the actual values of the books are bound to the items in the
list box.
<ListBox Name="lbBooks" Height="200"
Width="415" ItemTemplate ="{StaticResource BookTemplate}">
<ListBox.ItemsSource>
<Binding
Path="Elements[{http://www.mybooks.com}book]"/>
</ListBox.ItemsSource>
</ListBox>
Upon selecting a book in the list box,
we need to display the corresponding details in textboxes for viewing and
editing purposes. This requires a binding to the parent data source in the
listbox and a two way data binding so that the current values of the book
elements are displayed to and updated from the two text boxes in this panel.
Data binding to dynamic properties is similar to that used in the BookTemplate
data template:
<StackPanel Margin="1"
DataContext="{Binding ElementName=lbBooks, Path=SelectedItem}">
....
....
<TextBox
Name="editAttributeTextBox" Width="410" Text="{Binding
Path=Attribute[id].Value}">
...
...
<TextBox
Name="editValueTextBox" Width="410" Text="{Binding Path=Value}"
Height="25">
Walkthrough: Creating a WPF
application that shows LINQ to XML Data Binding with inline XML data
Now, let us create a complete
application that would make use of above discussed features. This sample program
enables the user to view and manipulate a list of books that is stored as an
embedded XML element.
Start Visual Studio and create a C# WPF
application named WPFDataBindingLinqToXml. The project must use the .NET
Framework 3.5 (or later).
Design the UI as shown in the
screenshot below as XAML markup in the Window1.Xaml.
Also, modify the code in
Window1.Xaml.cs file as below:
XNamespace mybooks =
"http://www.mybooks.com";
XElement bookList;
public Window1()
{
InitializeComponent();
bookList =
(XElement)((ObjectDataProvider)Resources["LoadedBooks"]).Data;
}
void OnRemoveBook(object sender,
EventArgs e)
{
int index =
lbBooks.SelectedIndex;
if (index < 0)
return;
XElement selBook =
(XElement)lbBooks.SelectedItem;
//Get next node before
removing element.
XNode nextNode =
selBook.NextNode;
selBook.Remove();
//Remove any matching newline
node.
if (nextNode != null
&& nextNode.ToString().Trim().Equals(""))
{ nextNode.Remove();
}
//Set selected item.
if (lbBooks.Items.Count >
0)
{ lbBooks.SelectedItem =
lbBooks.Items[index > 0 ? index - 1 : 0]; }
}
void OnAddBook(object sender,
EventArgs e)
{
if
(String.IsNullOrEmpty(tbAddID.Text) ||
String.IsNullOrEmpty(tbAddValue.Text))
{
MessageBox.Show("Please
supply both a Book ID and a Value!", "Entry Error!");
return;
}
XElement newBook = new
XElement(mybooks + "book", new XAttribute("id", tbAddID.Text),
tbAddValue.Text);
bookList.Add(" ", newBook,
"\r\n");
}
Basically, the above code uses the
XElement, XNode and XNamespace objects to manipulate Xml data along with binding
controls.
Lastly, build the solution by pressing
Ctrl+Shift+B, and then run it by pressing F5. The project should compile without
errors and run as a generic WPF application.
Using the WPFDataBindingLinqToXml
sample application and its User Interface
The top section of the UI displays the
raw XML that represents the book list. It is displayed using a WPF TextBlock
control, which does not enable interaction through the mouse or keyboard.
The second vertical section, labeled
Book List, displays the books as a plain text ordered list. It uses a ListBox
control that enables selection though the mouse or keyboard.
The following tasks may be performed in
this UI:
Ø To
delete an existing book from the list, select it in the Book List section, then
click the Remove Selected Book button. Notice that the book entry has been
removed from both the book and the raw XML source listings.
Ø To add
a new book to the list, enter values into the ID and ValueTextBox controls in
the last section, Add New Book, and then click the Add Book button. Note that
the book is appended to the list in both the book and XML listings. This program
does not validate input values.
Ø Select
the book entry in the second Book List section. Its current values should be
displayed in the third section.
Ø To
Edit Selected Book, Edit the values using the keyboard. As soon as either
TextBox control looses focus, changes are automatically propagated to the XML
source and book listings.
|