Showing posts with label Silverlight. Show all posts
Showing posts with label Silverlight. Show all posts

Tuesday, June 25, 2013

How to show List Box Items Horizontally in CRM 2011 using Silverlight

As we know default List box shows list of items in vertical Format. We need to scroll down to view all Items. If you want to show Items horizontally with the horizontal Scrollbar then it can be done with the following way:

1)      You need to first setup <ListBox> in XAML Design. <ListBox> should contain <ItemsPanelTemplate> to where it will change the default template of <ListBox> from vertical to horizontal by adding <StackPanel> with its orientation as "Horizontal".

<ListBox Name="imageList">
<ListBox.ItemsPanel>
              <ItemsPanelTemplate>
                 <StackPanel Name="horizontalOrientation" VerticalAlignment="Top" Orientation="Horizontal"/>
            </ItemsPanelTemplate>
       </ListBox.ItemsPanel>

       <ListBox.ItemTemplate>
              <DataTemplate>                           
                    <Border BorderBrush="Black" BorderThickness="1">
                            <StackPanel  Name="DataStack" Height="Auto" Width="Auto" Orientation="Vertical">                              
                                <StackPanel Orientation="Horizontal" Name="AccountName">
                                <TextBlock Name="Account" Text="Sub Account:" Width="100"/>
                                <Image Name="AccountImage" Source="/HorizontalListImagesView;component/Images/ico_16_1.png" Height="20" Width="20"/>
                                <TextBlock Name="AccountName" Text="{Binding Path=Name, Mode=TwoWay}"/>
                                </StackPanel>
                               
                                <StackPanel Orientation="Horizontal">
                                <TextBlock Name="Contact" Text="Primary Contact:" Width="100"/>
                                <Image Name="ContactImage" Source="/HorizontalListImagesView;component/Images/ico_16_2.png" Height="20" Width="20" />
                                <TextBlock Name="ContactName" Text="{Binding Path=PrimaryContactId.Name, Mode=TwoWay}"/>
                                </StackPanel>

                                <StackPanel Orientation="Horizontal">
                                <TextBlock Name="EmailAddress" Text="Email:"  Width="100"/>
                                <TextBlock Name="Email" Text="{Binding Path=EMailAddress1,Mode=TwoWay}"/>                               
                                </StackPanel>

                                <StackPanel Orientation="Horizontal">
                                <TextBlock Name="PhoneNumber" Text="Main Phone:" Width="100"/>
                                <TextBlock Name="Phone" Text="{Binding Path=Telephone1,Mode=TwoWay}"/>
                                </StackPanel>
                            </StackPanel>
                            </Border>
              </DataTemplate>
       </ListBox.ItemTemplate>
</ListBox>



2)      Now just design your List in Data Template and bind item Source to it. It will show following output.







Friday, September 14, 2012

Cross domain access from Silverlight

Silverlight control hosted at http://myserver/mypage.aspx can access only services on that same domain by default – for example http://myserver/service.svc, but not a service at http://otherserver/service.svc. This prevents a malicious Silverlight control hosted on the http://myserver domain from calling unauthorized operations on a service hosted on the http://otherserver domain.

To enable a Silverlight control to access a service in another domain, the service must explicitly opt-in to allow cross-domain access. By opting-in, a service states that the operations it exposes can safely be invoked by a Silverlight control, without potentially damaging consequences to the data that the service stores.

To allow cross domain access place clientaccesspolicy.xml and crossdomain.xml file at the root of the domain where the service is hosted. In the above example the file will be placed at the http://otherserver.
 
Create a clientaccesspolicy.xml file to allow the access from any other domain to service of the current domain.
 
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="SOAPAction">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>
 
There are three types of wildcards allowed:
 
1.      <domain uri=”*”/>:This option is used to allow access to all domains of the same scheme. An HTTP service will allow all HTTP callers. An HTTPS service will allow all HTTPS callers.
 
2.      <domain uri=”http://*”/> or <domain uri=”https://*”/>:The first option is used to allow access to HTTP service from HTTP callers and HTTPS service from HTTP callers. The second option is used to allow access to HTTP service from HTTPS callers and HTTPS service from HTTPS callers.
 
3.       <domain uri=”http://*.myserver.com”/>(subdomain):This option uses a wildcard at the first segment of the path ("http://*.contoso.com", for example) that allows all subdomains of the domain specified. So for the example.http://web.myserver.com would be allowed. Note that a uri path where the wildcard does not occur as a prefix (http://web.*.com, for example) is disallowed.
 
To prevent malicious attacks, you should never provide one client access policy file for both HTTP and HTTPS services on your domain that enable calls from both HTTP and HTTPS clients.
 
To allow access to specific domain, you need specify the particular uri e.g. <domain uri=”http://otherserver.com”/>. So http://myserver/service.svc service will be accessible from only http://otherserver.com (other domain).

You can implicitly deny access for all domains not listed in a <domain> element tag in a Silverlight policy file.

Create a crossdomain.xml file that contains the following configuration. The file must be configured to allow access to the service from any other domain, or it is not recognized by Silverlight 4.

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type"/>
</cross-domain-policy>
 

Monday, January 23, 2012

Update the Parent Silverlight Grid from the CRM form that is spawns.

We were working on the Silverlight REST Editor sample that is available in SDK.


We added a hyperlink to that grid that would open the CRM Contact form for the selected contact. This would allow users to check in further details of the contact. The users can also update the fields on the contact form there. Say the user edits the Phone on the Contact form instead of in the editable grid that we have presented them with… (users always tend to do what they are not supposed to do )

Now the issue raised was… after closing the CRM contact form, the changes made on the contact were not reflected in the grid. The user did not want to perform the search again to check the updated values…

How do we fix this…

1. Modify the Silverlight controls class and qualify it with the [ScriptableType] attribute.

[ScriptableType]
public partial class MainPage : UserControl
{

public MainPage( )
{
InitializeComponent( );

HtmlPage.RegisterScriptableObject("MainPage", this);

}

Register the control for access through script.

2. Next create qualify a method to be [ScriptableMember]

[ScriptableMember]
public void RefreshContactGrid( )
{
//Here write the code to rebind the Grid
}

Now we can access this method through jscript.

3. In the HTML page add a function to call the RefreshContractGrid method

function reloadContactGrid( ) {

try {
var control = document.getElementById("silverlightControl");
control.Content.MainPage.RefreshContactGrid( );
}
catch (e) {
alert(e.Description );
}
}

Silverlightcontrol refers to the object id of the silverlight control on the HTML page.
<object id="silverlightControl" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">

And “MainPageis the class name, which we have registered as Scriptable Object.

4. As we would like the grid to be auto-refreshed on the close of the CRM form. We need to write the code on the CRM form OnSave event to call the reloadContactGrid function of the HTML page. This function internally calls the Silverlight method that actually binds the grid once again and refreshes the datagrid.

function reloadParentGrid( ) {
try {

if (window.parent != null
&& window.parent.opener != null
&& window.parent.opener.document != null
&& window.parent.opener.document.nameProp != null
&& window.parent.opener.document.nameProp == "RESTContactEditor") {

window.parent.opener.reloadContactGrid( );

} //End of IF

} catch (e) { }
}

With these 4 steps you should be able to auto-refresh the grid after the user saves the CRM form that they opened from within the grid.


Wednesday, September 28, 2011

Debugging Silverlight Web Resources in CRM2011

In CRM2011, Silverlight Web resources can be debugged in Microsoft Visual Studio. For this you need to follow below steps:

• Build your Silverlight application.

• Upload the built version of the .xap file from the Web application project ClientBin folder.

• View your Silverlight application in the context it is designed to be used in.

• In your Silverlight application project, from the Visual Studio menu, select Debug and then Attach To Process….

• In the Attach to Process dialog box, find an iexplore.exe process where the Type column value is Silverlight, x86. (See below screen shot)



• Select that process and press Attach to close the dialog box and start debugging.

• In your Silverlight application project, set a breakpoint.

• Refresh the browser window or, in the Silverlight application, perform the action that you need to test your code.

Hope this help

Wednesday, July 27, 2011

Json and Silverlight with ODataService in CRM 2011

Dynamics CRM 2011 now provides the ability to perform data operations on CRM entities using JSON and ODATA service.

Here we have tried to explain the various clauses of JSON that is supported by CRM ODATA and how this service can be used in Silverlight as well as in Scripts. Note not all standard ODATA clauses are supported by CRM.

To use these clauses in silverlight you need to add a reference to the ODataService of the CRM i.e. OrganizationData.svc.

$select: This clause is the Select part of any SQL statement where you can specify the list of attributes to be returned by the query. Note you can also provide the collection property of a 1:N or N:1 relationship.

Using JSON

If you write the following URL to read the opportunity.

http://://xrmservices/2011/organizationdata.svc/OpportunitySet

it will return all columns of the opportunity in XML but if you want to read only the name you can add the select as follows.

http://ad12:5555/crmorg1//xrmservices/2011/organizationdata.svc/OpportunitySet?$select=Name

It will return the folliwng XML



Using Silverlight:

To use the $select in the Silverlight app you need to write the query as follows.

DataServiceQuery query = (DataServiceQuery_context.OpportunitySet.AddQueryOption("$select", "Name");


$expand: Directs that related records should be retrieved in the record or collection being retrieved.

Using JSON:
If you want to read the customer information with the opportunity while we are reading the opportunity by JSON then we can use the expand, and then we can read the customer details with the opportunity. Below we have given the JSON url.

http://://xrmservices/2011/organizationdata.svc/OpportunitySet?$expand=opportunity_customer_accounts,opportunity_customer_contacts&$select=*,opportunity_customer_accounts,opportunity_customer_contacts

Using Silverlight:

To use this with the silverlight you need to write the following query in the silverlight.

DataServiceQuery query = (DataServiceQuery)_context.OpportunitySet.AddQueryOption("$select", "*,opportunity_customer_accounts,opportunity_customer_contacts")
.AddQueryOption("$expand", "opportunity_customer_accounts")
.AddQueryOption("$expand", "opportunity_customer_contacts");

$filter:

Using JSON:
To set the condition in the JSON query we can use the $filter clause in the url.
Suppose if you want read all accounts of an user the JSON url will be as follows.

http:// ://xrmservices/2011/organizationdata.svc/AccountSet?$filter=OwnerId/Id eq (guid'34fca7f5-d556-e011-b9a8-00155d005515')

Using Silverlight:
In silverlight we can use the AddQueryOption to add the $filter as we use for $expand or we can use the Where Condition as shown in the below.

DataServiceQuery query = (DataServiceQuery)_context.AccountSet.Where(a => a.OwnerId.Id == new Guid("34FCA7F5-D556-E011-B9A8-00155D005515"));

To do it through AddQueryOption you can generate the filter in a string and then pass that string a parameter to the filter option. This provides us to create dynamic filters as shown below


filter += "new_testId eq (guid'" + _userid + "') ";

DataServiceQuery query = (DataServiceQuery)

query = query.AddQueryOption("$filter", filter);

$orderby: We can use it to set the sort order. Use it same as $filter.

Using JSON:

http:// ://xrmservices/2011/organizationdata.svc/AccountSet?$orderby=Name, Address1_Country.

Using Silverlight:

DataServiceQuery query = (DataServiceQuery)_context.OpportunitySet.AddQueryOption("$orderby", "Name, Address1_Country")


$top: To define the range that how many record want to read. Max limit is 50.

Using JSON:

http:// ://xrmservices/2011/organizationdata.svc/AccountSet?$top=10

Using Silverlight:

DataServiceQuery query = (DataServiceQuery)_context.OpportunitySet.AddQueryOption("$top", 10)


$skip: To define the that how many record want to skip.
Using JSON:

http:// ://xrmservices/2011/organizationdata.svc/AccountSet?$skip=10

Using Silverlight:

DataServiceQuery query = (DataServiceQuery)_context.OpportunitySet.AddQueryOption("$skip", 10)


NOTE: By default any query executed using ODATA service will only return 50 records at a time. If we want to display All records that exist even if it is more than 50 records, then you can use a combination use of the $skip and $top clauses to read all records.

For this you can recursively call this Query where _top will be const with value 50. And at each recursion we can increase the value of the _skip by 50.

DataServiceQuery query = (DataServiceQuery)_context.OpportunitySet.AddQueryOption("$skip", _skip).AddQueryOption("$top", _top)