Wednesday, September 14, 2011

Random tips for Windows 8 / WinRT

Check if you're in the designer:
bool Windows.ApplicationModel.DesignMode.DesignModeEnabled

Reflection:
Cast Type object to IReflectableType (maybe do an "as" and check for null?), and call IReflectableType.GetTypeInfo(). TypeInfo has access to members and properties and such.

XAML namespace declaration:
The old way looked like this:
xmlns:local="clr-namespace:SharkDice"
Now, use "using:":
xmlns:local="using:SharkDice"

Dispatcher (to invoke on UI thread):
Window.Current.CoreWindow.Dispatcher

ViewModels / MVVM / INotifyPropertyChanged:
None of the sample code uses MVVM, which is a little scary. Apparently INotifyPropertyChanged exists in System.ComponentModel and Windows.UI.Xaml.Data, but the only sample that uses either uses Windows.UI.Xaml.Data. Sometimes it gets a little weird and won't build though. Make sure everything builds and works correctly before you implement.

Event Accessors:
I couldn't get event accessors (add / remove) to work at all. Got some very strange build issues.

VS2011 XAML Design Surface Failure:

System.Runtime.Remoting.RemotingException

[3928] Designer process terminated unexpectedly!

Sometimes I get this error when I've written bad XAML, but twice I've put Visual Studio in a state where the designer is just permanently broken. I can open the same project on another Win8 machine and it works, but no amount of restarts, Cleans, etc. will bring back the design surface. For this reason I recommend doing dev work in a virtual machine or something you can easily and quickly recover or restore without losing your work.
NOTE: Doing a "refresh" (Metro Control Panel -> General -> Refresh your PC) fixed Visual Studio for me, but it was painful as I lost all my installed apps and some settings).
 
Things of question / note:
  • Why can Blend Preview only open HTML / JavaScript projects? Currently no easy way to edit templates and storyboards.
  • How to embed custom fonts? Silverlight and WPF methods don't work.
  • Replacement for Silverlight Projection? (Sad this is gone as I always hated that it wasn't in WPF)
  • Where is IsolatedStorage equivalent?
  • Where is non-generic IDictionary or equivalent?
  • Is there a replacement for Application.ApplicationLifetimeObjects? (not hard to replicate ourselves)

Monday, March 22, 2010

Windows Phone 7 Application Bar Templates

I created templates for the Application Bar images for myself and I'm sharing them in case they would be useful to anyone else. Here are the PSD and PNGs:
The PSD is broken up into layers so you can easily hide the template to save off your icon. Just stay within the white square on either template (inner 26x26) and you should be good to go.

http://cid-27c22899419e6236.skydrive.live.com/self.aspx/.Public/AppBarIconTemplate.png
http://cid-27c22899419e6236.skydrive.live.com/self.aspx/.Public/AppBarIconTemplate.psd

Boxee Launcher

Started another new Codeplex project: http://boxeelauncher.codeplex.com/

This is the sibling of Hulu Launcher. Boxee Launcher is a simple Windows Media Center add-in that attempts to launch Boxee and manage the windows as seamlessly as possible.

Monday, March 15, 2010

Hulu Launcher

Started a new Codeplex project: http://hululauncher.codeplex.com/
Hulu Launcher is a simple Windows Media Center add-in that attempts to launch Hulu Desktop and manage the windows as seamlessly as possible.

Check it out if you're into that sort of thing.

Friday, March 5, 2010

How to Create and Modify ClickOnce Manifests

Working with ClickOnce manifests can be a pain, especially if you need to integrate that work into your build process. There are several tools you can work with and potentially automate.
  1. mage.exe - This is the backing process behind mage.ui. In my opinion, mage.exe is the next step up from the "Publish" tab in Visual Studio -- it works, but only for basic cases. Comes with the .NET SDK.
  2. mt.exe - This is a great little tool that can validate, sign, and update the hashes in your manifests. It can also merge manifests and dump manifests from executables, as well as extract COM information to generate your own Reg-Free COM information (better than the Visual Studio build process does, actually -- most of our Reg-Free COM manifests are manually built with mt.exe).
  3. Microsoft.Build.Tasks.Deployment.ManifestUtilities - This namespace is a god-send, although it doesn't work with VSTO deployment manifests (in fact, it will probably mangle them). I believe the Visual Studio build process uses these classes internally, but I'm not sure. You can use this to modify application and deployment manifests in just about any way imaginable. To get access to this, add a reference to the Microsoft.Build.Tasks assembly. 

    To read a manifest using this, start at ManifestReader.ReadManifest(path) and work from there.
    To sign your manifests (or other files) from code, take a look at SecurityUtilities.SignFile(certThumbprint, timestampUrl, path)

Saturday, February 27, 2010

{x:Static} Replacement in Silverlight


So, there's no {x:Static} in Silverlight. That kind of sucks. I wrote this value converter to try to get around that. Unlike {x:Static}, you should put the whole path in the Source and avoid using the Binding.Path property. The converter should parse everything as needed. The code below doesn't support indexers of any kind, but it wouldn't be too hard to add.

You can use it in your XAML like this:
<local:BlockContainer Blocks="{Binding Source=Cubus.Game.CubusGame.Current.CurrentPlayer.Blocks, Converter={StaticResource static}}"/>

Here's the class. My apologies for the formatting.
 
public class StaticConverter : IValueConverter
{
#region IValueConverter Members

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is string))
{
throw new ArgumentException("Value must be of type string.");
}

try
{
string staticValue = (string)value;

// First we need to find the type
string typeName = null;
Type type = null;
int periodIndex = 0;
int lastPeriodIndex = staticValue.LastIndexOf(".");

while (type == null && periodIndex < lastPeriodIndex)
{
periodIndex = staticValue.IndexOf(".", periodIndex + 1);
typeName = staticValue.Substring(0, periodIndex);

// This bizarre block of code is how you enumerate through
// loaded assemblies in Silverlight. Normally you'd use
// AppDomain.Current.GetAssemblies() or something like that.
foreach (AssemblyPart ap in Deployment.Current.Parts)
{
System.Windows.Resources.StreamResourceInfo sri = Application.GetResourceStream(new Uri(ap.Source, UriKind.Relative));
System.Reflection.Assembly assembly = new AssemblyPart().Load(sri.Stream);
type = assembly.GetType(typeName);

if (type != null)
{
break;
}
}
}

if (type == null)
{
throw new NullReferenceException(string.Format("No type was found matching the name {0}.", typeName));
}

// Now let's find the value.
// After the type name, the first part of the path
// should be a static member. After that, the rest
// should be instance members.

object workingValue = null;
Type workingType = type;
string[] path = staticValue.Substring(periodIndex + 1, staticValue.Length - (periodIndex + 1))
.Split(new string[] { "." }, StringSplitOptions.None);

for (int i = 0; i < path.Length; i++)
{
BindingFlags flags;
if (i == 0)
{
flags = (BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.GetField | BindingFlags.Public);
}
else
{
flags = (BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.GetField | BindingFlags.Public);
}

PropertyInfo propInfo = workingType.GetProperty(path[i], flags);
if (propInfo != null)
{
workingValue = propInfo.GetValue(workingValue, null);
}
else
{
FieldInfo fieldInfo = workingType.GetField(path[i], flags);
if (fieldInfo != null)
{
workingValue = fieldInfo.GetValue(workingValue);
}
else
{
throw new NullReferenceException(string.Format("No properties or fields were found matching the name {0}.", path[i]));
}
}

workingType = workingValue.GetType();
}

return workingValue;
}
catch
{
if (DesignerProperties.GetIsInDesignMode(new UserControl()))
{
return DependencyProperty.UnsetValue;
}
else
{
throw;
}
}
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}

#endregion
}

Things in WPF that I wish were in Silverlight

  • {x:Static}
  • MultiBinding
  • Custom markup extensions
  • PropertyMetadata overrides
  • Adorners
  • Faster hit-testing
  • The Mouse class, being able to check mouse state without setting flags all over the place.