Friday, January 20, 2012

Application Logo

Reading this article in MSDN forums and taking the best (I hope) of what LR_ and Michael Washington offered as solutions I ended up with an extension class that allows you to put your application’s logo on the Ribbon Bar of any shell having one. You also have the choice to put it either on the left or the right. LR_’s original code was only modified in 2 points.
  1. You can decide if you want you Application Logo on the left or on the right of your commands.
  2. You don’t need to pass a URL to the image. The application’s logo (defined in project properties) is bound inspired by the XAML provided by Michael Washington.
I even left the LeftButtonDown part as it’s a good idea.

Although implied from the detailed reference to them I want to thank both guys for making it so easy for me to put my logo on screen.


    private static class LogoPlacement

    {

         public static void AddLogo(this Microsoft.LightSwitch.Client.IClientApplication application, System.Windows.HorizontalAlignment alignment) {

           Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() => { LogoPlacement.AddLogo(System.Windows.Application.Current.RootVisual, alignment); });

         }

      internal static void AddLogo(UIElement element, System.Windows.HorizontalAlignment alignment) {

        if (rcb != null) return;

 

        for (int i = 0; i < System.Windows.Media.VisualTreeHelper.GetChildrenCount(element); i++) {

          if (rcb != null)

            return;

          UIElement child = (UIElement)System.Windows.Media.VisualTreeHelper.GetChild(element, i);

          AddLogo(child, alignment);

        }

        if (element is Microsoft.LightSwitch.Runtime.Shell.Implementation.Standard.RibbonCommandBar) {

          rcb = element as Microsoft.LightSwitch.Runtime.Shell.Implementation.Standard.RibbonCommandBar;

          Image myImage = new Image() {

            Stretch = System.Windows.Media.Stretch.Uniform,

            Margin = new Thickness(2,8,14,8),

            HorizontalAlignment = alignment,

            Cursor = System.Windows.Input.Cursors.Hand

          };

          myImage.SetValue(ComponentViewModelService.ViewModelNameProperty, "Default.LogoViewModel");

          myImage.SetBinding(Image.SourceProperty, new System.Windows.Data.Binding { Path = new PropertyPath("Logo") });

          myImage.MouseLeftButtonUp += (s, e) => MessageBox.Show("Here may be some About...");

          myImage.SizeChanged += (s, e) => {

            double left = (s as Image).HorizontalAlignment == HorizontalAlignment.Left ? e.NewSize.Width + 10.0 : 0.0;

            double right = (s as Image).HorizontalAlignment == HorizontalAlignment.Right ? e.NewSize.Width + 10.0 : 0.0;

            rcb.Padding = new Thickness(left, 0, right, 0);

          };

          ((Grid)rcb.Parent).Children.Add(myImage);

        }

      }

 

      private static RibbonCommandBar rcb = null;

    }



14 comments:

  1. Hi Kostas,

    Can you clarify exactly where to place this code? I've tried a few places (screen code, application class) but I keep getting errors.

    Thanks,
    Liam

    ReplyDelete
  2. Ah, nevermind. I managed to combine this code with LR's original to suit my needs. Thanks :)

    ReplyDelete
  3. Hi Liam sorry I didn't manage to answer your question before finding it out. The reference to the original post was the reason there are so few explanations regarding the usage of the code. This is something like and appendix to the original thread :-). But given the timezone difference I believe I would manage to reply to you in any case.

    ReplyDelete
  4. Hello, would you mind explaining what this class should extend?
    I read the original topic on MSDN forums and, by using that, I would place this code into the Application.cs file, before the _Run() method for the default screen. Is that the place where you intend to put it, or is it different? Would it be possible ti clarify this?
    Thank you,

    Giovanni

    ReplyDelete
  5. Hi, Maggix this class is supposed to extend Microsoft.LightSwitch.Client.IClientApplication as its signature implies. In your _Run method you call this.AddLogo(...).
    One thing only change private static class to public static class so as to be able to use from anywhere. My mistake at pasting the code.

    ReplyDelete
  6. Hi Kostas, Its it possible for you to explain on how you did it, like steps am lost, are we supposed to have new class for LogoPlacement or what??

    ReplyDelete
    Replies
    1. Yes you add a new class called LogoPlacement to your client project and then in the application's first screen _CanRun you call this.AddLogo(...). I don't know how you work but another way is to add the class to a Silverlight class library that will be available to all your LS projects. Then where ever you want to use it you just have to declare using the namespace of your class. This is the only article that has questions, obviously a lot of people are interested so maybe I will post a sample in msdn lightswitch page to help.

      Delete
  7. Hello please can i have a step by step guide on where to place this code?
    I'm experienced with c# but new to LS.
    Exactly where do you place the code?
    Exactly where do you call the code?

    Many Many thanks.

    ReplyDelete
  8. Dan take a look here
    http://kostaschristodoulou.blogspot.com/2012/02/application-logo-sample.html

    ReplyDelete
  9. Hello you forgot to add that the Client project should reference

    C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\LightSwitch\1.0\Client\Microsoft.LightSwitch.Client.Internal.dll

    ReplyDelete
  10. This comment has been removed by a blog administrator.

    ReplyDelete
  11. Hi Kostas! Thank you for sharing first of all! I'm using VS 2013. So:
    *.DesktopClient => Add => Class => Visual Basic => Code => Class => ..saving your piece of code in there
    Once the class file opened in VS I get a lot of syntax errors. Am I doing anything wrong or the code needs to be amended?
    Much appreciated!
    Cooper

    P.S. I tried to download your example however could not open in VS 2013.

    ReplyDelete
  12. I realized the code is in C#.. my bad. Do you have an example, or maybe a link, to get the same in visual basic?
    Thank you
    Cooper

    ReplyDelete
    Replies
    1. No, unfortunately not. Should be rather straightforward to port though if you code VB.NET.

      Delete