Pages

Wednesday 5 June 2013

CRM Universal Search using silverlight 4.0

Universal search Functionality using Silverlight in CRM 2011

Using this functionality, we can search all records at one place or in one entity.


MainPage.xaml:

<UserControl x:Class="SLUniversalSearch.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="500" d:DesignWidth="700" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="71*" />
            <RowDefinition Height="409*" />
            <RowDefinition Height="20*" />
        </Grid.RowDefinitions>
        <StackPanel Name="stackPanel1" Orientation="Horizontal" Background="Azure">
            <sdk:Label Height="28" Name="lblSearch" Content=" Enter Text to search" Width="120" />
            <TextBox Height="23" Name="txtSearch" Width="200" TextChanged="txtSearch_TextChanged" />
        </StackPanel>
            <sdk:DataGrid Grid.Row="1" AutoGenerateColumns="False" Name="dgUniversalSearch" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible">
                <sdk:DataGrid.Columns>
                <sdk:DataGridTemplateColumn>
                    <sdk:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <CheckBox Name="chkSelected" IsChecked="{Binding Path=isSelected}" Checked="chkSelected_Checked" Unchecked="chkSelected_Unchecked"></CheckBox>
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellEditingTemplate>
                </sdk:DataGridTemplateColumn>
                <sdk:DataGridTextColumn CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Name" Width="Auto" Binding="{Binding Path=Name}" />
                    <sdk:DataGridTextColumn CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Entity Type" Width="Auto" Binding="{Binding Path=EntityType}" />
                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
            <sdk:Label Grid.Row="2" Name="lblCount" Height="20" Content=" Label" Background="WhiteSmoke"></sdk:Label>
    </Grid>
</UserControl>

MainPage.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
using SLUniversalSearch.CRMOData;
using System.Data.Services.Client;
using System.Collections.ObjectModel;
namespace SLUniversalSearch
{
    public partial class MainPage : UserControl
    {
        public MainViewModel mvm { get; set; }
        public SynchronizationContext synccontext;
        public CRMLINKContext context;
        UniversalSearch us;
        public string serverurl;
        public int count = 0,selectedcount=0;
        public MainPage()
        {
            InitializeComponent();
            synccontext = SynchronizationContext.Current;
            mvm = new MainViewModel();
            this.LayoutRoot.DataContext = mvm;
            serverurl = ServerUtility.GetServerUrl();
            context = new CRMLINKContext(new Uri(String.Format("{0}/xrmservices/2011/organizationdata.svc/", serverurl), UriKind.Absolute));
            context.IgnoreMissingProperties = true;
            loaddata();
        }
        public void loaddata()
        {
            DataServiceQuery<Lead> lquery = (DataServiceQuery<Lead>)context.LeadSet.Where(l => l.StateCode.Value == 0);
            lquery.BeginExecute(OnloadLead, lquery);
            DataServiceQuery<Contact> cquery = (DataServiceQuery<Contact>)context.ContactSet.Where(c => c.StateCode.Value == 0);
            cquery.BeginExecute(OnloadContact, cquery);
            DataServiceQuery<Account> aquery = (DataServiceQuery<Account>)context.AccountSet.Where(a => a.StateCode.Value == 0);
            aquery.BeginExecute(OnloadAccount, aquery);
        }
        public void OnloadLead(IAsyncResult result)
        {
            DataServiceQuery<Lead> lquery = result.AsyncState as DataServiceQuery<Lead>;
            ObservableCollection<Lead> leadCol = new DataServiceCollection<Lead>(lquery.EndExecute(result));
            foreach (Lead item in leadCol)
            {
                us = new UniversalSearch();
                us.Name = item.FullName;
                us.EntityType = "Lead";
                mvm.UniversalSearch.Add(us);
            }
        }
        public void OnloadContact(IAsyncResult result)
        {
            DataServiceQuery<Contact> cquery = result.AsyncState as DataServiceQuery<Contact>;
            ObservableCollection<Contact> contactCol = new DataServiceCollection<Contact>(cquery.EndExecute(result));
            foreach (Contact item in contactCol)
            {
                us = new UniversalSearch();
                us.Name = item.FullName;
                us.EntityType = "Contact";
                mvm.UniversalSearch.Add(us);
            }
        }
        public void OnloadAccount(IAsyncResult result)
        {
            DataServiceQuery<Account> aquery = result.AsyncState as DataServiceQuery<Account>;
            ObservableCollection<Account> accountCol = new DataServiceCollection<Account>(aquery.EndExecute(result));
            foreach (Account item in accountCol)
            {
                us = new UniversalSearch();
                us.Name = item.Name;
                us.EntityType = "Account";
                us.isSelected = false;
                mvm.UniversalSearch.Add(us);
            }
            dgUniversalSearch.ItemsSource = mvm.UniversalSearch;
            count = mvm.UniversalSearch.Count;
            lblCount.Content = (count > 0 ? "1-" : "0-") + mvm.UniversalSearch.Count + " of " + mvm.UniversalSearch.Count + "( " + selectedcount + " selected)";
           
        }

        private void txtSearch_TextChanged(object sender, TextChangedEventArgs e)
        {
            count = 0;
            selectedcount = 0;
            if (txtSearch.Text != null || txtSearch.Text!="")
            {
                dgUniversalSearch.ItemsSource = mvm.UniversalSearch.Where(u => u.Name.ToLower().Contains(txtSearch.Text.ToLower()) || u.EntityType.ToLower().Contains(txtSearch.Text.ToLower()));
                foreach (var item in dgUniversalSearch.ItemsSource)
                {
                    count++;
                }
                lblCount.Content = (count > 0 ? "1-" : "0-") + count + " of " + count + "( " + dgUniversalSearch.SelectedItems.Count + " selected)";
            }
            else
            {
                dgUniversalSearch.ItemsSource = mvm.UniversalSearch;
                foreach (var item in dgUniversalSearch.ItemsSource)
                {
                    count++;
                }
                lblCount.Content = (count > 0 ? "1-" : "0-") + count + " of " + count + "( " + dgUniversalSearch.SelectedItems.Count + " selected)";
            }
        }

        private void chkSelected_Checked(object sender, RoutedEventArgs e)
        {
            selectedcount++;
            lblCount.Content = (count > 0 ? "1-" : "0-") + count + " of " + count + "( " + selectedcount + " selected)";
        }

        private void chkSelected_Unchecked(object sender, RoutedEventArgs e)
        {
            selectedcount--;
            lblCount.Content = (count > 0 ? "1-" : "0-") + count + " of " + count + "( " + selectedcount + " selected)";
        }
    }
}



MainViewModel.Cs:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;
using SLUniversalSearch.CRMOData;

namespace SLUniversalSearch
{
    public class MainViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<UniversalSearch> UniversalSearch { get; set; }
        private UniversalSearch _selectedEntity;
        public UniversalSearch SelectedEntity
        {
            get { return _selectedEntity; }
            set
            {
                _selectedEntity = value;
                NotifyPropertyChanged("SelectedEntity");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public MainViewModel()
        {
            UniversalSearch = new ObservableCollection<UniversalSearch>();
            SelectedEntity = null;
        }
    }
    public class UniversalSearch
    {
        public string Name { get; set; }
        public string EntityType { get; set; }
        public bool isSelected { get; set; }
    }
}

ServerUtility.cs:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;

namespace SLUniversalSearch
{
    public static class ServerUtility
    {
        public static String GetServerUrl()
        {
            String serverUrl = String.Empty;
            serverUrl = GetServerUrlFromContext();
            return serverUrl;
        }
        private static String GetServerUrlFromContext()
        {
            try
            {
                ScriptObject xrm = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
                ScriptObject page = (ScriptObject)xrm.GetProperty("Page");
                ScriptObject pageContext = (ScriptObject)page.GetProperty("context");
                String serverUrl = (String)pageContext.Invoke("getServerUrl");
                return serverUrl;
            }
            catch
            {
                return String.Empty;
            }
        }
    }
}

SLUniversalSearchTestPage.html:
Add below line in header part
<script src="../ClientGlobalContext.js.aspx" type="text/javascript"></script>

Bulid the solution and add .xap and .html files to CRM webresources. Then see preview. You can get all active lead,contact and account records.

CRM Web resources Names:
1.new_/ClientBin/SLUniversalSearch.xap
2.new_/SLUniversalSearchTestPage.html

1 comment:

  1. Hi suresh great article..very usefull to CRM guys.

    ReplyDelete