Social Icons

twitter google plus linkedin rss feed

Pages

Showing posts with label WinRT. Show all posts
Showing posts with label WinRT. Show all posts

23.11.12

StratexStudio is in the Store

image
A couple of days ago we finally managed to get StratexStudio certified and published.

Our StratexLive users will be able to connect to their company site using their credentials and the StratexLive URL and start using their Surfaces to show the other board members how good their enterprises are doing and how shiny their new Windows 8 devices are.

The new application has dashboards to measure the Performance, Risks and Controls as well as the activity in the portal and a nested view of the organization hierarchy.

Have a look at the Windows Store page of the StratexStudio to get more pictures and if you have Windows 8 download it and give it a go, it’s free.

No comments:

Post a Comment

15.11.12

Click works but Tapped Crashes on Windows 8

Our app has been rejected from the store because it crashes when the user taps in a GridView. As we don’t have a proper surface we were using the simulator to test our software but with the mouse tool not with the finger and it was working perfectly…

It crashes every time you tap in an item in a GridView and it’s funny, funny peculiar, not funny ha ha, because it crashes right in the tap, the code doesn't even get to the call-back, it just crashes. The crash info is not useful, as expected.

Looks like there’s a bug in the GridView and after it’s assigned to a populated DataContext it needs to be refreshed before it accepts Taps, even though it works fine with Clicks.

There’s no way or I haven’t found it of refreshing the UI in WinRT which I reckon it will solve this issue, so I have taken two different approaches to solve this bug.

  • Fast loading dashboards: I am preloading the contents of the fast loading dashboards once the app is executed. Doing this I get all of the GridViews populated in a page that is not being displayed to the users, in the background. Once the page where the GridView is selected by the user it’s rendered along with the GridView object refreshing it.
  • Slow loading dashboards: I am preloading the contents on this dashboards too but if the user clicks them right after the app loads they will still be loading causing the GridView to render just once after the DataContext is populated. In this cases I have changed the behaviour of the dashboard and I’m assigning the DataContext before and updating it several times, once every new chunk of data is received. This way the GridView gets refreshed once per chunk of new information and the issue with the tapping is solved.

The guys at the Windows Store App Lab said they will find a proper solution to this issue but I think this is the kind of bug that will be fixed through windows update. Anyway I’ll keep you posted if they come back with something new.

***UPDATE***
A Microsoft's expert pointed out that if you create and populate the GridView in code and add it to the page  it will work as expected. I've tested this and it's true.

The templates in my GridViews are complex so I'll make them user controls so I can create and populate them in code without loosing the MVVM approach. I still haven't tested this.

No comments:

Post a Comment

6.9.12

Authenticating an ASMX Web Service in SharePoint from a WinRT app

Where’s the CookieContainer?

Yes mate, I’ve had that question too.

We are creating a new application for Windows 8 and we need it to connect to our web services. Connecting to the anonymous methods was easy, but when it comes to authenticating the user the situation changes.

I was pretty confident, in this context confident is an euphemism for ignorant and naive,  I could use the same approach I used when I was creating my apps for WP7 I have used it a thousand times and WP7 is more or less the same as WinRT so who would have thought it won’t work?
Well WinRT is not the same as WP7.

After creating the SPAuthBridge class I tried to add the authentication cookie to my SoapClient as usual but as you probably now if you are reading this post this line doesn’t work:

MySoapClient.CookieContainer = SharePointAuth.cookieJar;

In WinRT the SoapClient object doesn’t have a CookieContainer object so we have to find another way of adding the cookie in the calls.

The SPAuthBridge is OK. I have just added a new method to it to get the authentication cookie as string from the cookie container.
public string GetAuthenticationCookie()
{
    return string.Format("{0}={1}", "FedAuth",
            cookieJar.GetCookies(new System.Uri("https://www.mySite.com"))["FedAuth"].Value);
}

Then all you have to do is to follow the steps in the previous post to authenticate and after you have successfully authenticated to SharePoint you have to change the way you add the cookie to your SoapClient.

I have found two ways:

The quick one

Every time you need to call the web service you have to add the cookie to the header and then call the web service in the same OperationContextScope. It looks like this:
using (new OperationContextScope(MyWS.InnerChannel))
{
    HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();

    httpRequestProperty.Headers[System.Net.HttpRequestHeader.Cookie] = SharePointAuth.GetAuthenticationCookie();

    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

    UserInfo = await MyWS.GetInfoForUserAsync();
}

That’s easy but it’s not very readable and if you have to call a lot of web services you’ll probably get bored of this approach.

The elegant one

Instead of manually adding the cookie every time we can also create a behaviour that does it automatically.

In order to do that you need to create a CookieBehavior class. I copied 99% of mine from here and it looks like this:
class CookieBehaviour: IEndpointBehavior
{
    private string cookie;

    public CookieBehaviour(string cookie)
    {
        this.cookie = cookie;
    }

    public void AddBindingParameters(ServiceEndpoint serviceEndpoint,
        BindingParameterCollection bindingParameters) { }

    public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
    {
        behavior.ClientMessageInspectors.Add(new CookieMessageInspector(cookie));
    }

    public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint,
        EndpointDispatcher endpointDispatcher) { }

    public void Validate(ServiceEndpoint serviceEndpoint) { }
}

public class CookieMessageInspector : IClientMessageInspector
{
    private string cookie;

    public CookieMessageInspector(string cookie)
    {
        this.cookie = cookie;
    }

    public void AfterReceiveReply(ref Message reply,
        object correlationState) { }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        HttpRequestMessageProperty httpRequestMessage;
        object httpRequestMessageObject;
        if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name
            , out httpRequestMessageObject))
        {
            httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
        }
        else
            httpRequestMessage = new HttpRequestMessageProperty();

        httpRequestMessage.Headers[System.Net.HttpRequestHeader.Cookie] = cookie;
        request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);

        return null;
    }
}

Once you have this class the only thing you have to do is to add this behaviour to your web service on the initialization and your cookie will be added automatically every time.
public MyWSSoapClient InitializeMyWS()
{
    BasicHttpBinding Bind = new BasicHttpBinding();

    //////////////////////Transport///////////////////////
    Bind.Security.Mode = BasicHttpSecurityMode.Transport;
    //////////////////////////////////////////////////////

    /////////////////////MessageSize//////////////////////
    Bind.MaxReceivedMessageSize = Int32.MaxValue;
    //////////////////////////////////////////////////////

    EndpointAddress oAddress = new EndpointAddress(SiteUrl + "/_vti_bin/MyWS.asmx");
    MyWSSoapClient MyWS = new MyWSSoapClient(Bind, oAddress);

    CookieBehaviour AuthCookieBehaviour = new CookieBehaviour(SharePointAuth.GetAuthenticationCookie());
    MyWS.Endpoint.EndpointBehaviors.Add(AuthCookieBehaviour);

    return MyWS;
}

After you have initialized the web service like this you can call your methods without worrying about the authentication any more:
private async Task<ObservableCollection<Info>> GetInfo()
{
    GetInfoForUserResponse Information = await MyWS.GetInfoForUserAsync();

    return Information.Body.GetInfoForUserResult;
}
The transport is necessary in my case because I am calling a web service hosted in an HTTPS web application by default is set to None and I was getting an ArgumentException like this:

The provided URI scheme 'https' is invalid; expected 'http'.

And the MaxReceivedMessageSize could also be a wee bit excessive. Tune it to suit your needs but be aware that if you set it too small you’ll get a nice CommunicationException saying that:

The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.

Have fun with the tablet if you have one, I am still waiting for mine.

9 comments:

Post a Comment

5.9.12

Dependency Property with Call-back and default value snippet

For me this is the way Microsoft should have created the DependencyProperty snippet from the beginning.
I use this one a lot and it has a placeholder for the default value and the call-back method I am even assigning the instance that called the call-back to a property in the snippet.
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
 <CodeSnippet Format="1.0.0">
  <Header>
   <Title>Dependency Property With CallBack</Title>
   <Shortcut>propdpCallBack</Shortcut>
   <Description>Creates a dependency property with it's callback method</Description>
   <Author>Jose Sanchez</Author>
   <SnippetTypes>
    <SnippetType>Expansion</SnippetType>
    <SnippetType>SurroundsWith</SnippetType>
   </SnippetTypes>
  </Header>
  <Snippet>
   <Declarations>
    <Literal>
     <ID>PublicName</ID>
     <Default>PropertyName</Default>
     <ToolTip>Public name of the depencency property</ToolTip>
    </Literal>
    <Literal>
     <ID>type</ID>
     <Default>string</Default>
     <ToolTip>Type of the property</ToolTip>
    </Literal>
    <Literal>
     <ID>ParentClassType</ID>
     <Default>UserControl</Default>
     <ToolTip>Type of the parent class of the dependency property</ToolTip>
    </Literal>
    <Literal>
     <ID>DefaultValue</ID>
     <Default>string.Empty</Default>
     <ToolTip>Default value of the dependency property</ToolTip>
    </Literal>
    <Literal>
     <ID>CallBackName</ID>
     <Default>PropertyCallBackName</Default>
     <ToolTip>Name of the callback method that will be triggered when the depencency property has changed</ToolTip>
    </Literal>
   </Declarations>
   <Code Language="csharp"><![CDATA[public $type$ $PublicName$
        {
            get { return ($type$)GetValue($PublicName$Property); }
            set { SetValue($PublicName$Property, value); }
        }

        // Using a DependencyProperty as the backing store for $PublicName$.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty $PublicName$Property =
            DependencyProperty.Register("$PublicName$", typeof($type$), typeof($ParentClassType$), new PropertyMetadata($DefaultValue$, new PropertyChangedCallback($CallBackName$)));


 private static void $CallBackName$(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            $ParentClassType$ Changed$ParentClassType$ = (obj as $ParentClassType$);

            //TODO: Implement some actions in Changed$ParentClassType$
        }]]>
   </Code>
  </Snippet>
 </CodeSnippet>
</CodeSnippets>
I hope you find it as useful as I do.

By the way, you can find more info about how creating and importing your code snippets here.

No comments:

Post a Comment

22.11.10

Code Snippets in C# and Why my TwoWay Bindings are not working?

Well, regarding to the problem with the TwoWay binding, today I’ve learnt that they don’t work magically; each property should implement the Property Change Notification, the INotifyPropertyChanged. It’s not that complex, It takes a little more time to declare the property this way (by the way, you have it perfectly explained here) and this leads us to the Code Snippets thing.

Creating code snippets is one of those things I’ve left to learn later a lot of times… until today that I had to create an object with more than thirty properties launching the PropertyChanged event and I couldn’t delay it further.
To increase my productivity I have wasted a little of time and I have created a code snippet for the properties implementing the INotifyPropertyChanged. I’ve called it propNot I’m this creative, I can’t help it
To do so, in Visual Studio, I went to Tools and from there to Code Snippets Manager. There I chose C# and then I copied the address of the My Code Snippets folder.

I created a .snippet file on that folder with this content
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
 <CodeSnippet Format="1.0.0">
  <Header>
   <Title>propNot</Title>
   <Shortcut>propNot</Shortcut>
   <Description>Code snippet for properties with NotifyPropertyChanged</Description>
   <Author>Chan</Author>
   <SnippetTypes>
    <SnippetType>Expansion</SnippetType>
    <SnippetType>SurroundsWith</SnippetType>
   </SnippetTypes>
  </Header>
  <Snippet>
   <Declarations>
    <Literal>
     <ID>privName</ID>
     <Default>privName</Default>
     <ToolTip>Private name of the property</ToolTip>
    </Literal>
    <Literal>
     <ID>pubName</ID>
     <Default>pubName</Default>
     <ToolTip>Public name of the property</ToolTip>
    </Literal>
    <Literal>
     <ID>type</ID>
     <Default>string</Default>
     <ToolTip>Type of the property</ToolTip>
    </Literal>
   </Declarations>
   <Code Language="csharp"><![CDATA[private $type$ $privName$;
        
    public $type$ $pubName$
    {
     get { return $privName$; }

     set
     {
      $privName$ = value;
      // Call NotifyPropertyChanged when the property is updated
      NotifyPropertyChanged("$pubName$");
     }
    }]]>
   </Code>
  </Snippet>
 </CodeSnippet>
</CodeSnippets>
It’s tested and working, both the TwoWay binding and the Code Snippet.

Now that I know how to do them I think I’ll do them really usually. --EDIT-- I lied, I don't do them that usually because I am VERY lazy, but I do use this other snippet a lot:
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
 <CodeSnippet Format="1.0.0">
  <Header>
   <Title>INotify region with the necessary methods to implement the interface</Title>
   <Shortcut>inotifyregion</Shortcut>
   <Description>Creates region with the necessary methods to implement the interface INotifyPropertyChanged</Description>
   <Author>Jose Sanchez</Author>
   <SnippetTypes>
    <SnippetType>Expansion</SnippetType>
    <SnippetType>SurroundsWith</SnippetType>
   </SnippetTypes>
  </Header>
  <Snippet>
   <Declarations />
   <Code Language="csharp"><![CDATA[#region INotifyMethods
        // Declare the event
        public event PropertyChangedEventHandler PropertyChanged;

        // Create the OnPropertyChanged method to raise the event
        protected void NotifyPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
        #endregion]]>
   </Code>
  </Snippet>
 </CodeSnippet>
</CodeSnippets>

No comments:

Post a Comment