Skip to content

Instantly share code, notes, and snippets.

@bergerjac
Created April 5, 2012 00:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bergerjac/2306969 to your computer and use it in GitHub Desktop.
Save bergerjac/2306969 to your computer and use it in GitHub Desktop.
LightSwitch Custom Logo
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace LightSwitchApplication
{
public partial class Application
{
// Example Usage
partial void CreateNewSTARTUP_SCREEN_ENTITY_Run(ref bool handled)
{
LogoHelper.AddLogo(
() => new Image { Source = ResourcesHelper.GetImage("logo.png") },
//() => new Image { Source = new BitmapImage(new Uri(@"http://i1.social.s-msft.com/Profile/u/avatar.jpg?displayName=Yann%20Duran&size=extralarge&version=b818459d-a8a9-4aae-8923-0e38e5b281da")) },
img =>
{
img.Stretch = Stretch.Uniform;
img.MaxHeight = 65;// ~ default height of ribbon command bar
img.HorizontalAlignment = HorizontalAlignment.Right;
img.MouseLeftButtonUp += (s, e) => MessageBox.Show("Here may be some About...");
img.Cursor = Cursors.Hand;
});
}
}
}
// Client
// {ProgramFiles}\Microsoft Visual Studio 10.0\Common7\IDE\LightSwitch\1.0\Client\Microsoft.LightSwitch.Client.Internal.dll
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.LightSwitch.Runtime.Shell.Implementation.Standard;
using Microsoft.LightSwitch.Threading;
namespace LightSwitchApplication
{
///<summary>Provides helpful members to an app's logo.</summary>
public static class LogoHelper
{
///<summary>Adds the specified image as a logo to the application.</summary>
/// <param name="logoFunc">A function for obtaining the logo.
/// <remarks>Must be a function because a value cannot cross thread.</remarks></param>
/// <param name="logoAction">An action to perform on the logo.</param>
public static void AddLogo<TLogo>(this Func<TLogo> logoFunc, Action<TLogo> logoAction = null)
where TLogo : FrameworkElement
{
if (isLogoAdded) { return; }
Dispatchers.Main.BeginInvoke(() =>
{
FindRibbonCommandBarAndApplyLogo(
System.Windows.Application.Current.RootVisual,
logoFunc(),
logoAction ?? (logo => { })// if logoAction is null -> do nothing
);
});
}
static bool isLogoAdded = false;
///<summary>Find RibbonCommandBar and add logo/image. <remarks>Recursive.</remarks></summary>
private static void FindRibbonCommandBarAndApplyLogo<TLogo>(
UIElement element,
TLogo logo,
Action<TLogo> logoAction)
where TLogo : FrameworkElement
{
if (isLogoAdded) { return; }
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
{
UIElement child = (UIElement)VisualTreeHelper.GetChild(element, i);
FindRibbonCommandBarAndApplyLogo(child, logo, logoAction);
}
RibbonCommandBar ribbonCmdBar = element as RibbonCommandBar;
if (ribbonCmdBar == null) { return; }// element NOT RibbonCommandBar
logoAction(logo);// perform Action on logo
ApplyLogo(ribbonCmdBar, logo); // apply logo
}
///<summary>Applies the logo.</summary>
/// <param name="logoSibling">The sibling control that the logo will appear over the top of.</param>
/// <param name="logo">Source of the logo.</param>
/// <param name="imgAction">Action to apply to the logo.</param>
static void ApplyLogo(Control logoSibling, FrameworkElement logo)
{
logo.SizeChanged += (s, e) => // occurs when collapser is clicked
ReSize(logoSibling, logo, e.NewSize);
((Panel)logoSibling.Parent).Children.Add(logo);
isLogoAdded = true;
}
///<summary>Applies appropriate margin and padding to logo and logo sibling.</summary>
static void ReSize(Control logoSibling, FrameworkElement logo, Size newSize)
{
Thickness siblingPadding = new Thickness(0, 0, 0, 0);
Thickness logoMargin = new Thickness(2, 2, 2, 14);
double paddedSide = (newSize.Width + 12);
switch (logo.HorizontalAlignment)
{
case HorizontalAlignment.Left:
siblingPadding.Left += paddedSide;
break;
case HorizontalAlignment.Right:
siblingPadding.Right += paddedSide;
logoMargin.Right += 15;//compensate for collapse arrow
break;
}
logo.Margin = logoMargin;
logoSibling.Padding = siblingPadding;
}
}
}
// Client
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Media.Imaging;
namespace LightSwitchApplication
{
///<summary>Provides helpful members for accessing resources.</summary>
public static class ResourcesHelper
{
///<summary>Gets the bytes from an embedded resource.</summary>
public static byte[] GetEmbeddedBytes(this string fileName)
{
string resName = "LightSwitchApplication.Resources." + fileName;
using (Stream resStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resName))
{
return GetStreamAsByteArray(resStream);
}
}
private static byte[] GetStreamAsByteArray(Stream stream)
{
if (stream == null) { return null; }
var streamLength = Convert.ToInt32(stream.Length);
byte[] fileData = new byte[streamLength];
stream.Read(fileData, 0, streamLength);
return fileData;
}
///<summary>Gets an image from an embedded resource file.</summary>
public static BitmapImage GetImage(this string filename)
{
filename = filename.ToUpper();
Stream stream = null;
Assembly asm = Assembly.GetExecutingAssembly();
foreach (var streamName in asm.GetManifestResourceNames())
{
if (streamName.ToUpper().EndsWith(filename) == false)
{// NOT the resource -> try next
continue;
}
Debug.WriteLine(streamName);
stream = asm.GetManifestResourceStream(streamName);
Debug.Assert(stream != null);
break;
}
BitmapImage img = new BitmapImage();
img.SetSource(stream);
return img;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment