Wednesday, October 6, 2010

WPF - Find a Control from DataTemplate in WPF

In this article i will show you how to find control from datatemplate in WPF.


In this example I will bind tables name from northwind database into a listbox and get an only those tables name which user will selected on listbox.


Step 1
Create a WPF Application.


Step 2
Add a listbox and button on window,it is look like this


<Grid>
        <ListBox Height="181" HorizontalAlignment="Left" Margin="179,12,0,0" Name="listBox1" VerticalAlignment="Top" Width="159"/>
        <Button x:Name="btnOk" Height="23" Width="80" Margin="219,210,204,78" Content="OK" Click="btnOk_Click"></Button>
    </Grid>

Step 3
Create datatemplate for listbox,it is look like this
<Window.Resources>
        
        <DataTemplate x:Key="CheckListBox">
            <StackPanel Orientation="Horizontal">
                
                <CheckBox Name="ChkList" IsChecked="True" Content="{Binding Path=name}"></CheckBox>
               
            </StackPanel>
        </DataTemplate>
    </Window.Resources>  

Data Template are a similar concept as Control Template. They give you a very flexible and powerful solution to replace the visual appearance of a data item in a control like ListBox, ComboBox or ListView.

Content Property -  Bind the tables name in checkbox.Display tables name in checkbox.
Binding Path=name - name is represent the tables name of northwind database.it is column name of sys.tables
IsChecked Property - Gets or sets whether the checkbox is checked.


Step 4
Apply a datatemplate on listbox,it is look like this

<ListBox Height="181" HorizontalAlignment="Left" Margin="179,12,0,0" Name="listBox1" VerticalAlignment="Top" Width="159" 

ItemTemplate="{StaticResource 
CheckListBox}" ItemsSource="{Binding}" />


ItemTemplate Property - Gets or sets the datatemplate used to display each item.

ItemSource Property- Gets or sets a collection used to generate the content of the itemsControl.


Step 5
Get tables name from northwind database.write a GetTableName method in code behind,it is look like this
/// <summary>
        /// Get table name from nortwind databases
        /// </summary>
        /// <returns>DataTable</returns>
        private DataTable GetTableName()
        {
            try
            {
                SqlConnection SqlCon = new SqlConnection();
                SqlCon.ConnectionString = @"Data Source=shree\shree;Initial Catalog=Northwind;Integrated Security=True";
                SqlCon.Open();

                SqlCommand SqlComm = new SqlCommand("SELECT [name] FROM sys.tables");
                SqlComm.Connection = SqlCon;

                DataTable Table = new DataTable();
                SqlDataAdapter SqlDa = new SqlDataAdapter();
                SqlDa.SelectCommand = SqlComm;
                SqlDa.Fill(Table);

                return Table; 
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);  
            }
        }

Bind the tables name in listbox.
private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                listBox1.DataContext = GetTableName(); // Bind Tables Name in ListBox
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

Step 6
Find child control from ContentPresenter.it is look like this
 /// <summary>
        /// Find Child Control from ContentPresenter
        /// </summary>
        /// <typeparam name="ChildControl"></typeparam>
        /// <param name="DependencyObj"></param>
        /// <returns></returns>
        private ChildControl FindVisualChild<ChildControl>(DependencyObject DependencyObj)
        where ChildControl : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(DependencyObj); i++)
            {
                DependencyObject Child = VisualTreeHelper.GetChild(DependencyObj, i);

                if (Child != null && Child is ChildControl)
                {
                    return (ChildControl)Child;
                }
                else
                {
                    ChildControl ChildOfChild = FindVisualChild<ChildControl>(Child);

                    if (ChildOfChild != null)
                    {
                        return ChildOfChild;
                    }
                }
            }
            return null;
        }

Step 7
Get a selected checkbox items from listbox,it is look like this

/// <summary>
        /// Get a selected checkbox items
        /// </summary>
        private void GetSelectedCheckObjItem()
        {
            try
            {
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    // Get a all list items from listbox
                    ListBoxItem ListBoxItemObj = (ListBoxItem)listBox1.ItemContainerGenerator.ContainerFromItem(listBox1.Items[i]);

                    // find a ContentPresenter of that list item.. [Call FindVisualChild Method]
                    ContentPresenter ContentPresenterObj = FindVisualChild<ContentPresenter>(ListBoxItemObj);

                    // call FindName on the DataTemplate of that ContentPresenter
                    DataTemplate DataTemplateObj = ContentPresenterObj.ContentTemplate;
                    CheckBox Chk = (CheckBox)DataTemplateObj.FindName("ChkList", ContentPresenterObj);

                    // get a selected checkbox items.
                    if (Chk.IsChecked == true)
                    {
                        MessageBox.Show(Chk.Content.ToString().Trim()); 
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);  
            }
        }

Call GetSelectedCheckObjItem method on button click event.
private void btnOk_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                GetSelectedCheckObjItem(); // Get a selected checkbox items
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);   
            }
        }

Full Code

1. XAML Code

<Window x:Class="WPF_CheckListBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    
    <Window.Resources>
        
        <DataTemplate x:Key="CheckListBox">
            <StackPanel Orientation="Horizontal">
                
                <CheckBox Name="ChkList" IsChecked="True" Content="{Binding Path=name}"></CheckBox>
               
            </StackPanel>
        </DataTemplate>
    </Window.Resources>  
    
    <Grid>
        <ListBox Height="181" HorizontalAlignment="Left" Margin="179,12,0,0" Name="listBox1" VerticalAlignment="Top" Width="159" ItemTemplate="{StaticResource CheckListBox}" ItemsSource="{Binding}" />
        <Button x:Name="btnOk" Height="23" Width="80" Margin="219,210,204,78" Content="OK" Click="btnOk_Click"></Button>
    </Grid>
</Window>

2. Code Behind

using 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;
using System.Data;
using System.Data.SqlClient;   

namespace WPF_CheckListBox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                listBox1.DataContext = GetTableName(); // Bind Tables Name in ListBox
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        private void btnOk_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                GetSelectedCheckObjItem(); // Get a selected checkbox items
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);   
            }
        }

        #region Methods
        /// <summary>
        /// Get table name from nortwind databases
        /// </summary>
        /// <returns>DataTable</returns>
        private DataTable GetTableName()
        {
            try
            {
                SqlConnection SqlCon = new SqlConnection();
                SqlCon.ConnectionString = @"Data Source=shree\shree;Initial Catalog=Northwind;Integrated Security=True";
                SqlCon.Open();

                SqlCommand SqlComm = new SqlCommand("SELECT [name] FROM sys.tables");
                SqlComm.Connection = SqlCon;

                DataTable Table = new DataTable();
                SqlDataAdapter SqlDa = new SqlDataAdapter();
                SqlDa.SelectCommand = SqlComm;
                SqlDa.Fill(Table);

                return Table; 
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);  
            }
        }

        /// <summary>
        /// Find Child Control from ContentPresenter
        /// </summary>
        /// <typeparam name="ChildControl"></typeparam>
        /// <param name="DependencyObj"></param>
        /// <returns></returns>
        private ChildControl FindVisualChild<ChildControl>(DependencyObject DependencyObj)
        where ChildControl : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(DependencyObj); i++)
            {
                DependencyObject Child = VisualTreeHelper.GetChild(DependencyObj, i);

                if (Child != null && Child is ChildControl)
                {
                    return (ChildControl)Child;
                }
                else
                {
                    ChildControl ChildOfChild = FindVisualChild<ChildControl>(Child);

                    if (ChildOfChild != null)
                    {
                        return ChildOfChild;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// Get a selected checkbox items
        /// </summary>
        private void GetSelectedCheckObjItem()
        {
            try
            {
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    // Get a all list items from listbox
                    ListBoxItem ListBoxItemObj = (ListBoxItem)listBox1.ItemContainerGenerator.ContainerFromItem(listBox1.Items[i]);

                    // find a ContentPresenter of that list item.. [Call FindVisualChild Method]
                    ContentPresenter ContentPresenterObj = FindVisualChild<ContentPresenter>(ListBoxItemObj);

                    // call FindName on the DataTemplate of that ContentPresenter
                    DataTemplate DataTemplateObj = ContentPresenterObj.ContentTemplate;
                    CheckBox Chk = (CheckBox)DataTemplateObj.FindName("ChkList", ContentPresenterObj);

                    // get a selected checkbox items.
                    if (Chk.IsChecked == true)
                    {
                        MessageBox.Show(Chk.Content.ToString().Trim()); 
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);  
            }
        }

        #endregion
    }
}


Download
Download Source Code

No comments:

Post a Comment