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

20 comments:

  1. Nice post! I really needed something like this! Thanks a lot!

    ReplyDelete
  2. Your good knowledge and kindness in playing with all the pieces were very useful. I don’t know what I would have done if I had not encountered such a step like this.
    AWS Training in Bangalore
    AWS training in sholinganallur
    AWS training in Tambaram
    AWS training in Velachery

    ReplyDelete
  3. I am really happy with your blog because your article is very unique and powerful for new.

    Selenium Training in Pune

    ReplyDelete
  4. Data analyst generally works on creation of reports based on company’s data driven KPI’s(generally involves descriptive analytics), whereas Data scientists understand business and domain along with the technicalities to understand what will happen in future(more on descriptive + predictive analytics both)
    Etlhive is a data science institute in pune. actuelly we wanted to promote our website on your site will you please contact me discus further details

    website: - www.etlhive.com
    contact: - +91 8055020011

    ReplyDelete