Windows Presentation Foundation (WPF) has provided many features for developing Data Driven applications. Using the DataBinding feature of WPF, effective data representation can easily be achieved. WPF allows developers to define an instance of the Data Access Object directly in XAML. ObjectDataProvider is one of the effective mechanisms for DataBinding in WPF. We use this provider if the application contains a separate Data Access Layer. ObjectDataProvider defines the instance of the class and makes call to the various methods of the class. Follow these steps to use the ObjectDataProvider for Databinding in WPF applications
Step 1: In VS 2010, create a WPF application and name it as ‘WPF40_Database’. To this application, add a new class file and name it as ‘DataAccessLayer.cs’. Write the following code in it:
Note: To reduce code, I haven’t used the try-catch-finally block but make sure you do that in your application. Alternatively use the using block to release resources, once they are used.
using System;
using System.Collections.ObjectModel;
using System.Data.SqlClient;
namespace WPF40_Database
{
public class ImageEmployee
{
public int EmpNo { get; set; }
public string EmpName { get; set; }
public int Salary { get; set; }
public int DeptNo { get; set; }
public byte[] EmpImage { get; set; }
}
public class CDataAccess
{
ObservableCollection<ImageEmployee> _EmpCollection;
public ObservableCollection<ImageEmployee> EmpCollection
{
get { return _EmpCollection; }
set { _EmpCollection = value; }
}
public CDataAccess()
{
_EmpCollection = new ObservableCollection<ImageEmployee>();
}
public ObservableCollection<ImageEmployee> GetEmployees()
{
SqlConnection conn =
new SqlConnection("Data Source=.;Initial Catalog=Company;" +
"Integrated Security=SSPI");
SqlCommand cmd = new SqlCommand();
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "Select * from ImageEmployee";
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
EmpCollection.Add(
new ImageEmployee()
{
EmpNo = Convert.ToInt32(reader["EmpNo"]),
EmpName = reader["EmpName"].ToString(),
Salary = Convert.ToInt32(reader["Salary"]),
DeptNo = Convert.ToInt32(reader["DeptNo"]),
EmpImage = (byte[])reader["EmpImage"]
});
}
reader.Close();
conn.Close();
return EmpCollection;
}
}
}
The above code contains two classes ‘ImageEmployee’ - which defines properties compatible to the Table column and the class ‘CDataAccess’, with a method called ‘GetEmployees()’ which makes a call to the database and retrieves rows from the table. The code in this method stores all the data in an ObservableCollection<T>.
Step 2: Open MainWindow.xaml and write the following XAML code:
<Window x:Class="WPF40_Database.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:WPF40_Database"
Title="MainWindow" Height="350" Width="912">
<Window.Resources>
<ObjectDataProvider x:Key="objDs"
ObjectType="{x:Type data:CDataAccess}"
MethodName="GetEmployees">
</ObjectDataProvider>
<DataTemplate x:Key="EmpDataTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding EmpName}"></TextBlock>
<Image Source="{Binding EmpImage}" Height="60" Width="60"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource objDs}}">
<ComboBox Height="80" HorizontalAlignment="Left" Margin="29,30,0,0"
Name="lstEmployee" VerticalAlignment="Top" Width="274"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource EmpDataTemplate}"
IsSynchronizedWithCurrentItem="True"/>
<TextBox Height="23" HorizontalAlignment="Left" Margin="688,70,0,0"
Name="textBox1" VerticalAlignment="Top" Width="120"
Text="{Binding EmpNo}"/>
<TextBox Height="23" HorizontalAlignment="Left" Margin="688,114,0,0"
Name="textBox2" VerticalAlignment="Top" Width="120"
Text="{Binding EmpName}"/>
<TextBox Height="23" HorizontalAlignment="Left" Margin="688,160,0,0"
Name="textBox3" VerticalAlignment="Top" Width="120"
Text="{Binding Salary}"/>
<TextBox Height="23" HorizontalAlignment="Left" Margin="688,204,0,0"
Name="textBox4" VerticalAlignment="Top" Width="120"
Text="{Binding DeptNo}"/>
<Image Height="66" HorizontalAlignment="Left" Margin="688,233,0,0"
Name="image1"
Stretch="Fill" VerticalAlignment="Top" Width="120"
Source="{Binding EmpImage}"/>
<TextBlock Height="23" HorizontalAlignment="Left" Margin="487,70,0,0"
Name="textBlock1" Text="EmpNo" VerticalAlignment="Top"
Width="169" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="487,117,0,0"
Name="textBlock2" Text="EmpName" VerticalAlignment="Top"
Width="169" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="487,163,0,0"
Name="textBlock3" Text="Salary" VerticalAlignment="Top"
Width="169" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="487,207,0,0"
Name="textBlock4" Text="DeptNo" VerticalAlignment="Top"
Width="169" />
</Grid>
</Window>
The above code defines ObjectDataProvider with key ‘objDs’ in Windows Resources. This creates an instance of the ‘CDataAccess’ class using ‘ObjectType’ attribute of the ObjectDataProvider, and using MethodName attribute, the ‘GetEmployees’ method from the ‘CDataAccess’ class is specified. The DataTemplate ‘EmpDataTemplate’ defines the Visual Structure for Data representation. The ObjectDataProvider ‘objDs’ is bound with the Grid. The DataTemplate ‘EmpDataTemplate’ is assigned to the ‘ItemTemplate’ property of the Combobox. The individual TextBox is bound with the property from the ‘ImageEmployee’ property.
Step 3: Run the application and the following result will be displayed. Select any value from the Combobox and the respective details will be displayed in the TextBoxes.
Tweet
3 comments:
where is older post button on devcurry front page
A really unique post. How easy it is in WPF to display images from database but I was unaware until I read your article. Thanks alot
Thank you for sharing. This was very useful to me.
Post a Comment