Friday, December 31, 2010

Twitter caption contest launched for Half-Minute Hero sequel

As practice for the kind of quick thinking required to play Hero 30 Second ... and to promote Hero 30 Second (mostly that last one), Japanese publisher Marvelous has launched a Twitter caption contest. Participants are asked to come up with clever captions for a selected screenshot in 100 characters or less.

Of course, given the nature of the game, participants are also limited to 30 seconds. After you've come up with your impromptu masterpiece, it'll go on the "Twitter30" website and your own Twitter feed. As 1UP notes, it's technically a Japanese contest, but there's likely someone at Marvelous who will be able to read and appreciate your frantic attempts at humor.

JoystiqTwitter caption contest launched for Half-Minute Hero sequel originally appeared on Joystiq on Fri, 31 Dec 2010 22:00:00 EST. Please see our terms for use of feeds.

Permalink | Email this | Comments

Thandie Newton Liz Phair Aaliyah Katherine Heigl Lorri Bagley

Blog Post: PowerShell to change the UIVersion on a subweb in SharePoint 2010

Recently ran into the need to revert a specific web back to the SharePoint 2007 UI after an upgrade to SharePoint 2010.  The main reason for the change was a custom masterpage that was not ready for the 2010 styles and ribbon.  After the UI was upgraded, the masterpage rendering was pretty bad.  The Site Actions menu would render behind the contents of the page, the layout was completely out of whack.

I put together a couple lines of PowerShell that will do this for a specific web.  In our case, we upgraded the database using Mount-SPContentDatabase ?UpdateUserExperience, then ran the PowerShell below to revert just that one subweb.  This allowed all the other content to pick up the 2010 UI.  For example, if you have a subweb at http://teams/sub1/sub2 that needs to be the 2007 UI, you could use:

   1: $web = Get-SPWeb http://sharepoint.domain.com/sub1/sub2
   2: $web.UIVersion = 3
   3: $web.Update()
 
After the initial upgrade testing, we found there were subwebs underneath sub2 that also needed the 2007 UI.  I put together the following which enumerates all the subwebs under a specific subweb and switches them to the 2007 UI..  Put the script into a PS1 file and run it from there.
   1: function ChangeUIVersion($web)
   2: {
   3:         $web.UIVersion = 3
   4:     $web.Update()
   5: }
   6:  
   7: function ProcessSubWebs($currentWeb)
   8: {
   9:         ChangeUIVersion($currentWeb)
  10:  
  11:     foreach($sub in $currentWeb.Webs)
  12:     {
  13:         ChangeUIVersion($sub)
  14:  
  15:         if($sub.Webs.Count -gt 0)
  16:         {
  17:             ProcessSubWebs($sub)    
  18:         }
  19:     }
  20: }
  21:  
  22: ProcessSubWebs(Get-SPWeb -identity http://sharepoint.domain.com/sub1/sub1/)
  23:  

Melissa Howard Samantha Mumba Busy Philipps Thora Birch Jennifer Garner

Blog Post: Slide Re-Use is Audience Abuse!

Today's subject is all about whether you should re-use other people slides in your PowerPoint deck. 

   

This is a once good practice that has been terribly abused.  It all starts innocently enough, say John gives a great presentation and then Fred finds out about it and then asks to borrow the deck so they can use it in their presentation.  Then a couple of things generally happen.

  1. Fred inserts John's complete so slide deck into the middle of their own already 40 slide presentation and proceed to make some monster mega deck.  The resulting bastardized deck no longer has a coherent story framework and is often just way too long.
  2. Fred has no idea how to present John's slides because John did not do complete slide notes.  John just handed over the slides to Fred with no supporting information.  When Fred presents the slides he reads directly from every slide because that’s all the information he has to present with.  And so the audience abuse continues.

     

So what can a presenter do?

 

First, don't reuse someone else's slides if you can avoid it.  Period.  But like every good rule there are always exceptions and here is how I like to think about each one.

  • LIMIT THE TOTAL NUMBER OF REUSED SLIDES:  Don't copy someone else's slide deck in its entirety and just re-use it.  Usually I will select a few slides that I really need and use them.  I never reuse a whole deck.  There are two exceptions to this rule.
    1.  Teaching - Is someone has constructed a great classroom presentation I will use it in its entirety as long as it comes with good slide notes so I'm not just reading from the screen.  I will usually rework some of the examples and stories in the deck so they are personalized in my voice, using my stories and experience. 
    2.  Pitching - Same with a Pitch deck, especially sales decks.  It is a good practice, but whenever I give someone a pitch deck I will spend an hour with them teaching them the story behind the deck and make sure they personalize it.
  • THE SINGLE CANONICAL SLIDE:  One other good practice when re-using slides is to simply pick that one canonical slide from the other person's deck and use it in a framing slide.  One of the most common scenarios that exist is that someone in your organization will have created a single great slide that somehow explains your organizations current strategy.  These are great slides to reuse as when you are framing your own story, such as when you might need to do a nod to your company's larger strategy.  One note though, use it quickly and move on.  Don't dwell on it as it is simply a framing slide for your later argument.
  • INCLUDE NOTES:  I never give slides to another presenter without good notes and talking points.  A well designed slide is often just the top level point you are trying to drive home and there is often significant text needed to properly frame and explain that top level point.  Whenever I reuse myself or give someone a slide to reuse, it is a good idea to have these notes and talking points lest you become simply another poor presenter who can only read the text on the slide to your audience.
  • IMPROVE THE SLIDE DON’T JUST REUSE IT:  I almost always improve any slide that I'm given.  One of the side benefits of this is that when I rework a slide, I become intimately familiar with the content and the context in which I are going to reuse it.

  

Best Practice:  I never reuse a slide that doesn't fit neatly within my story frame.  Remember that you are trying to tell a cogent story and if you include a slide that detracts from your story you weaken your argument.  This is the penultimate reason for including or not including a slide that you want to reuse.

  

  

One last thought.  I like to think of presenters at the 100, 200, 300, and the 500 level.  

  • *100 level are those that are new to presenting and are new to their roles. 
  • *200 level are presenters who have done a fair amount of presenting and are comfortable, but not especially technically proficient at putting together a great visual presentation. 
  • *300 level are advanced presenters who can put together good story frames, good visuals, and deliver well. 
  • *500 level are the experts and generally work in senior communications roles doing very advanced presentations. 

  

100 and 200 level presenters are the biggest abusers of slide reuse.  If this is where you are at, please don't just reuse.  Take into account what I've laid out here today if you are going to reuse someone else's slides.

 

Ping me back on email and let me know how well it works for you.

 

DK

mailto:dkarle@microsoft.com

Melissa George Cameron Richardson Chandra West Kasey Chambers Megan Ewing

Analyst: RIM PlayBook tablet's performance comes at a cost

Analysts may have located the future BlackBerry tablet's weak spot: battery life. According to Kaufman Bros. analyst Shaw Wu, the BlackBerry PlayBook currently in the works at Research in Motion suffers from a battery lifespan that can't compete with the tablets it's designed to take down, including the Samsung Galaxy Tab and the Apple iPad.

According to All Things D, Wu's sources have told him that the PlayBook currently only lasts "a few hours" per charge. For comparison, the Galaxy Tab lasts about six hours, and the iPad has significantly more screen space yet churns out more than 10 hours under moderate use.

This is likely due to the nature of the operating system the PlayBook uses, called QNX. QNX was designed for other systems that are perpetually plugged in, like network equipment or interfaces in cars, and isn't optimized for maximum performance on a minimal power source.

Wu speculates that the PlayBook's release date was pushed back to May 2011 to cope with this issue, though there are a limited number of fixes. A larger battery could help, but with space and weight at a premium in tablets, it's not a very elegant fix.

Under RIM-controlled conditions, the PlayBook appeared to perform admirably against the iPad; it's too bad that this performance might come at such a battery life tax.

Read the comments on this post


Gina Carano Sanaa Lathan Ana Beatriz Barros Maria Menounos Shakira

Joystiq Top 10 of 2010: Alan Wake

Turns out we'd been thinking of "episodic" gaming the wrong way. Episodic pioneers like Telltale long-since realized that consumers won't stick around episode to episode unless they buy the season upfront; so, episodic gaming isn't so much about a new business model as it is about a new (well, for gaming at least) method of storytelling. And that's where Alan Wake comes in.

When Finnish game developer Remedy Entertainment announced it was turning in wronged NYPD cop Max Payne's badge and gun, only to pick up mystery writer Alan Wake's uh, pen ... and hoodie ... it was clear something was different. Over the game's prolonged five-year development cycle, Alan Wake morphed from an open-world, sandbox-style game set in the Pacific Northwest's fictional town of Bright Falls to a carefully scripted, episodic creation that had more in common with Twin Peaks than Grand Theft Auto.

Continue reading Joystiq Top 10 of 2010: Alan Wake

JoystiqJoystiq Top 10 of 2010: Alan Wake originally appeared on Joystiq on Fri, 31 Dec 2010 14:00:00 EST. Please see our terms for use of feeds.

Permalink | Email this | Comments

Lorri Bagley Leslie Bega Maria Sharapova Lindsay Price Zoe Saldana

Best of the Rest: Richard's picks of 2010

Castlevania: Lords of Shadow
There are more than a few complaints floating around that Castlevania: Lords of Shadow isn't a real Castlevania title. I would argue that Lords of Shadow is more Castlevania than many recent entries in the series. I think fans tend to forget (or overlook) that Castlevania began as a linear action title. For me, the series has never been about completing the map. It's about exploring wonderful and sinister places, which Lords of Shadow packs in spades. When I played the 8-bit Castlevania 2: Simon's Quest as a child, I saw lots of blocky pixels, but what I imagined is perfectly represented by Lords of Shadow. From stinking bogs to dark forests and forgotten castles, all is so meticulously and lovingly crafted that my seven-year-old self was enthralled with every moment.

I'll take that over the same 13-year-old sprites any day.

Continue reading Best of the Rest: Richard's picks of 2010

JoystiqBest of the Rest: Richard's picks of 2010 originally appeared on Joystiq on Thu, 30 Dec 2010 09:00:00 EST. Please see our terms for use of feeds.

Permalink | Email this | Comments

Vanessa Hudgens Sarah Michelle Gellar Olivia Munn Melissa Sagemiller Roselyn Sanchez

Groupon: Fresh Financing Sets Stage for Late 2011 IPO

Trader Mark submits:

Whatever the valuation, the story of Groupon is just amazing; this company was not even in existence 10 quarters ago... and now has turned down a deal to be bought by Google (GOOG) for $6 billion (Nov. 30, 2010: From Startup in 2008 to Potential $5-$6B Buyout from Google in 2010). Just as awe inspiring is its revenue over $1 billion in 2 years... incredible.

Judging by the valuation, the rabid "it's 1999 all over again, just replace Alan with Ben" investors have placed on the Youku's (YOKU) of the world (which in a word is cuckoo!), Groupon might be worth $20 billion (Dec. 13, 2010: Careful About that Youku on Your Shoe). I'm not saying this is a sensible valuation, but with easy money flying out of every orifice and a major dearth of high growth companies in our country, any visible rapid growers are going to attract mounds of money. In Youku terms, Facebook should be worth more than Apple (AAPL) + Exxon (XOM) combined...


Complete Story »

Cristina Dumitru Cat Power January Jones Christina DaRe Malin Akerman

Scott Pilgrim DLC finally drops on Xbox 360, but users report it doesn't work

Here's the thing: Technically, you can download the Knives Chau add-on pack for Scott Pilgrim vs The World, which adds the titular, ever-pining youngster to the game's cast of characters, along with a PvP arena, special dodgeball mode and drop-in, drop-out offline co-op, but it won't do you any good. At least right now it won't.

Those who've already downloaded the DLC are reporting that they can't access any of the new goods at all. At this point, accessing the DLC seems dependent on a title update. We've contacted both Microsoft and Ubisoft for clarification on the issue and will let you know what we find out.

Continue reading Scott Pilgrim DLC finally drops on Xbox 360, but users report it doesn't work

JoystiqScott Pilgrim DLC finally drops on Xbox 360, but users report it doesn't work originally appeared on Joystiq on Thu, 30 Dec 2010 01:30:00 EST. Please see our terms for use of feeds.

Permalink | Email this | Comments

Victoria Pratt Shakara Ledard Vanessa Marcil Rachel McAdams Kristin Cavallari

Skype gives customers $1 for last week's downtime

Skype gives customers $1 for last week's downtimeLast week, Skype had its second-longest outage, ever, with most of its users being unable to access the service for just over 24 hours.

Today, Skype explained what happened, which I will post a snippet of here:
On Wednesday, December 22, a cluster of support servers responsible for offline instant messaging became overloaded. As a result of this overload, some Skype clients received delayed responses from the overloaded servers. In a version of the Skype for Windows client (version 5.0.0152), the delayed responses from the overloaded servers were not properly processed, causing Windows clients running the affected version to crash.

Users running either the latest Skype for Windows (version 5.0.0.156), older versions of Skype for Windows (4.0 versions), Skype for Mac, Skype for iPhone, Skype on your TV, and Skype Connect or Skype Manager for enterprises were not affected by this initial problem.

However, around 50% of all Skype users globally were running the 5.0.0.152 version of Skype for Windows, and the crashes caused approximately 40% of those clients to fail. These clients included 25�30% of the publicly available supernodes, also failed as a result of this problem.


As part of an apology for the downtime, Skype has given a credit voucher to paying members, of $1. That $1 can get you around 30 minutes of international calls, says the company.

Permalink | Comments



Natalie Imbruglia Patricia Velásquez Jennifer Morrison Adrianne Palicki Amanda Righetti

Dragon Age 2, Your Shape and Disney come to Xbox Live Avatar Marketplace

The Avatar Marketplace has received a bunch of new items, including Dragon Age 2 gear, some Your Shape: Fitness Evolved props and ... Disney sidekicks? Sure enough, you can own your own virtual version of Sebastian from The Little Mermaid. Talk about a sentence we never thought we'd have to write.

Pricing on these new Avatar duds is pretty much par for the course. Your Shape and Disney sidekick props will run you 240 MS Points ($3) a piece, while some of the more complex Dragon Age 2 ensembles will set you back upwards of 400 MS Points ($5). Hit the links below for your preferred Avatar gear.

JoystiqDragon Age 2, Your Shape and Disney come to Xbox Live Avatar Marketplace originally appeared on Joystiq on Thu, 30 Dec 2010 23:00:00 EST. Please see our terms for use of feeds.

Permalink | Email this | Comments

Jennifer Morrison Adrianne Palicki Amanda Righetti Michelle Branch Melissa Howard

Editors' Picks: Best of 1UP 2010

Feature

Header

Editors' Picks: Best of 1UP 2010

We select some of our favorite stories and videos from 1UP this year.

By: 1UP Staff

We published a lot of great content on 1UP in 2010, more than we could possibly remember. A lot of it is timeless and deserves a second look, but often gets lost in the shuffle of new stuff.

Kristin Kreuk Molly Sims Monika Kramlik Lacey Chabert Amber Brkich

Thursday, December 30, 2010

So Much for 'Free': Apple Will Sell $2 Billion in Apps in 2011

TechCrunch submits:

By Sarah Lacy

I’ve often wondered if the early Web pioneers had it all to do over again if Web companies would have put less of an emphasis on free.


Complete Story »

Kasey Chambers Megan Ewing Kristanna Loken Aubrey ODay Drew Barrymore

Apple facing class action suit over iOS data collection

Apple and several other app developers are the target of a class action lawsuit filed late last week in the Northern District of California. The lawsuit alleges that some apps are collecting so much analytic information that users can be personally identified, while Apple remains complacent in allowing apps to collect the information despite a privacy policy that ostensibly forbids it.

The lawsuit was filed on behalf of Jonathan Lalo of Los Angeles, and singles out Apple, Pandora, The Weather Channel, Dictionary.com, and Backflip, makers of Paper Toss. These apps, among others, collect and transmit varying types of demographic data back to Apple and the app makers, and some developers also share the demographic information with various mobile ad networks. Most of this data is also attached to a particular iPhone or iPad's UDID—the unique device identification number.

Read the rest of this article...

Read the comments on this post


Brittany Murphy Britney Spears Amanda Swisten Scarlett Chorvat Kim Smith

A year in Infinite Loop: 2010's most popular stories

2010 was a big year for Apple, as it saw the debut not only of the iPhone 4, but the iPad. There were also some new MacBook Airs and a 12-core beast of a Mac Pro. Your top 10 stories from Infinite Loop follows.

Ars Technica reviews the iPad: Six Ars staffers, four days, one new Apple product—inside is everything you wanted to know about the iPad, plus a whole bunch of stuff you didn't know that you wanted to know. We did everything: watching, listening, reading, gaming, and working with the iPad. Here's what we learned.

Read the rest of this article...

Read the comments on this post


Monica Bellucci Minki van der Westhuizen Katharine Towne Malia Jones Jennifer ODell

Blog Post: Write your own Linq query viewer

Sometimes you just want to see data in a tabular format. It could be stored in a server somewhere in the cloud, in a SQL server, a FoxPro database, an EntityFramework object, or just a local object. You’d like to see all columns, without having to write code to select each column.

 

Linq allows you to create a query of the data, regardless of where it lives.  The resulting query is strongly typed, (i.e. a column each for Name and Age, with the appropriate data types).

 

However, it’s not easy to write code that works generically with any Linq query: each one can have a different shape, like the number and datatype of the columns.

 

Below is a sample of C# code (VB code is here) that shows a general purpose class called “Browse”. (FoxPro has a command called Browse, which just presents all the data in a navigable grid format.) Try using the various sample queries, or create your own.

 

You can just create an instance of Browse, passing in the Linq query as an argument. The Browse figures out the rows and columns from the Linq query using reflection.

 

The sample also shows how to use a value converter, which will take strings that are too long and truncate them to fit in a browse. The value converter also adds commas to large numbers, like “1,000,000”.

 

If you want to show real database data, do this: Project->Add New Item-> Ado.Net Entity Model. The Entity Model Data Wizard starts up. Generate from Database. Give it a connection to your data. Select a table. Fiddle with the Entity and table name in the code below and/or the Entity designer (intellisense will work)

 

Start Visual Studio: File->New->Project->C#->WPF Application. Name it WpfApplication1

Replace the MainWindow.xaml.cs with the code below

 

See also:

Use DataTemplates and WPF in code to create a general purpose LINQ Query results display

Use LINQ to Foxpro or any SQL data and display it in a WPF form using DataSetExtensions and DataRowExtensions

Path Markup Syntax

WPF: How to create Styles in code/and magical Content

 

<Sample Code>

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

using System.Collections;

using System.Data.Objects.DataClasses;

using System.Reflection;

using System.Diagnostics;

using System.ComponentModel;

 

namespace WpfApplication1

{

    /// <summary>

    /// Interaction logic for MainWindow.xaml

    /// </summary>

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

            this.Loaded += new RoutedEventHandler(this.Window_Loaded);

        }

 

        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            var dockPanel = new DockPanel();

            var btnRefresh = new Button()

            {

                Content = "_Refresh",

                HorizontalAlignment = System.Windows.HorizontalAlignment.Left,

                MaxWidth = 100

            };

            DockPanel.SetDock(btnRefresh, Dock.Top);

            this.Content = dockPanel;

            btnRefresh.Click += delegate

            {

                dockPanel.Children.Clear();

                dockPanel.Children.Add(btnRefresh);

                //var ent = new MyEntities();

                //var br = new Browse(from logs in ent.Customers.ToArray() // ToArray so not readonly                                                           

                //                    //where logs.TimeStamp > DateTime.Now.AddDays(-4)

                //                    orderby logs.ID descending

                //                    select logs

                //                    );

 

                var br = new Browse(from proc in System.Diagnostics.Process.GetProcesses() select proc);

 

                //var br = new Browse(from file in System.IO.Directory.GetFiles(

                //                                Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)

                //                        )

                //                    select new System.IO.FileInfo(file)

                //                    );

 

                //var br = new Browse(from typ in this.GetType().GetMembers() select typ);

 

                //var br = new Browse(from ProcessThread thrd in System.Diagnostics.Process.GetCurrentProcess().Threads select thrd );

 

 

                //var br = new Browse(from ProcessModule mod in Process.GetCurrentProcess().Modules select mod);

 

                dockPanel.Children.Add(br);

            };

            btnRefresh.RaiseEvent(new RoutedEventArgs(Button.ClickEvent, this));

        }

    }

 

    public class Browse : ListView

    {

        public Browse(IEnumerable query)

        {

            this.Margin = new System.Windows.Thickness(8);

            this.ItemsSource = query;

            var gridvw = new GridView();

            this.View = gridvw;

            var ienum = query.GetType().GetInterface(typeof(IEnumerable<>).FullName);

 

            var members = ienum.GetGenericArguments()[0].GetMembers().Where(m => m.MemberType == System.Reflection.MemberTypes.Property);

            foreach (var mbr in members)

            {

                if (mbr.DeclaringType == typeof(EntityObject)) // if using Entity framework, filter out EntityKey, etc.

                {

                    continue;

                }

                var gridcol = new GridViewColumn();

                var colheader = new GridViewColumnHeader() { Content = mbr.Name };

                gridcol.Header = colheader;

                colheader.Click += new RoutedEventHandler(colheader_Click);

                gridvw.Columns.Add(gridcol);

 

                // now we make a dataTemplate with a Stackpanel containing a TextBlock

                // The template must create many instances, so factories are used.

                var dataTemplate = new DataTemplate();

                gridcol.CellTemplate = dataTemplate;

                var stackPanelFactory = new FrameworkElementFactory(typeof(StackPanel));

                stackPanelFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);

 

                var txtBlkFactory = new FrameworkElementFactory(typeof(TextBlock));

                var binder = new Binding(mbr.Name)

                {

                    Converter = new MyValueConverter() // truncate things that are too long, add commas for numbers

                };

                txtBlkFactory.SetBinding(TextBlock.TextProperty, binder);

                stackPanelFactory.AppendChild(txtBlkFactory);

                txtBlkFactory.SetBinding(TextBlock.ToolTipProperty, new Binding(mbr.Name)); // the tip will have the non-truncated content

 

                txtBlkFactory.SetValue(TextBlock.FontFamilyProperty, new FontFamily("courier new"));

                txtBlkFactory.SetValue(TextBlock.FontSizeProperty, 10.0);

 

                dataTemplate.VisualTree = stackPanelFactory;

            }

            // now create a style for the items

            var style = new Style(typeof(ListViewItem));

 

            style.Setters.Add(new Setter(ForegroundProperty, Brushes.Blue));

 

            var trig = new Trigger()

            {

                Property = IsSelectedProperty,// if Selected, use a different color

                Value = true

            };

            trig.Setters.Add(new Setter(ForegroundProperty, Brushes.Red));

            trig.Setters.Add(new Setter(BackgroundProperty, Brushes.Cyan));

            style.Triggers.Add(trig);

 

            this.ItemContainerStyle = style;

        }

 

        private ListSortDirection _LastSortDir = ListSortDirection.Ascending;

        private GridViewColumnHeader _LastHeaderClicked = null;

        void colheader_Click(object sender, RoutedEventArgs e)

        {

            GridViewColumnHeader gvh = sender as GridViewColumnHeader;

            if (gvh != null)

            {

                var dir = ListSortDirection.Ascending;

                if (gvh == _LastHeaderClicked) // if clicking on already sorted col, reverse dir

                {

                    dir = 1 - _LastSortDir;

                }

                try

                {

                    var dataView = CollectionViewSource.GetDefaultView(this.ItemsSource);

                    dataView.SortDescriptions.Clear();

 

                    var sortDesc = new SortDescription(gvh.Content.ToString(), dir);

                    dataView.SortDescriptions.Add(sortDesc);

                    dataView.Refresh();

                    if (_LastHeaderClicked != null)

                    {

                        _LastHeaderClicked.Column.HeaderTemplate = null; // clear arrow of prior column

                    }

                    SetHeaderTemplate(gvh);

                    _LastHeaderClicked = gvh;

                    _LastSortDir = dir;

                }

                catch (Exception)

                {

                    // some types aren't sortable

                }

            }

        }

 

        void SetHeaderTemplate(GridViewColumnHeader gvh)

        {

            // now we'll create a header template that will show a little Up or Down indicator

            var hdrTemplate = new DataTemplate();

            var dockPanelFactory = new FrameworkElementFactory(typeof(DockPanel));

            var textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));

            var binder = new Binding();

            binder.Source = gvh.Content; // the column name

            textBlockFactory.SetBinding(TextBlock.TextProperty, binder);

            textBlockFactory.SetValue(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Center);

            dockPanelFactory.AppendChild(textBlockFactory);

 

            // a lot of code for a little arrow

            var pathFactory = new FrameworkElementFactory(typeof(Path));

            pathFactory.SetValue(Path.FillProperty, Brushes.DarkGray);

            var pathGeometry = new PathGeometry();

            pathGeometry.Figures = new PathFigureCollection();

            var pathFigure = new PathFigure();

            pathFigure.Segments = new PathSegmentCollection();

            if (_LastSortDir != ListSortDirection.Ascending)

            {//"M 4,4 L 12,4 L 8,2"

                pathFigure.StartPoint = new Point(4, 4);

                pathFigure.Segments.Add(new LineSegment() { Point = new Point(12, 4) });

                pathFigure.Segments.Add(new LineSegment() { Point = new Point(8, 2) });

            }

            else

            {//"M 4,2 L 8,4 L 12,2"

                pathFigure.StartPoint = new Point(4, 2);

                pathFigure.Segments.Add(new LineSegment() { Point = new Point(8, 4) });

                pathFigure.Segments.Add(new LineSegment() { Point = new Point(12, 2) });

            }

            pathGeometry.Figures.Add(pathFigure);

            pathFactory.SetValue(Path.DataProperty, pathGeometry);

 

            dockPanelFactory.AppendChild(pathFactory);

            hdrTemplate.VisualTree = dockPanelFactory;

 

            gvh.Column.HeaderTemplate = hdrTemplate;

        }

    }

 

    public class MyValueConverter : IValueConverter

    {

        private const int maxwidth = 70;

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            if (null != value)

            {

                Type type = value.GetType();

                //trim len of long strings. Doesn't work if type has ToString() override

                if (type == typeof(string))

                {

                    var str = value.ToString().Trim();

                    var ndx = str.IndexOfAny(new[] { '\r', '\n' });

                    var lenlimit = maxwidth;

                    if (ndx >= 0)

                    {

                        lenlimit = ndx - 1;

                    }

                    if (ndx >= 0 || str.Length > lenlimit)

                    {

                        value = str.Substring(0, lenlimit);

                    }

                    else

                    {

                        value = str;

                    }

                }

                else if (type == typeof(Int32))

                {

                    value = ((int)value).ToString("n0"); // Add commas, like 1,000,000

                }

                else if (type == typeof(Int64))

                {

                    value = ((Int64)value).ToString("n0"); // Add commas, like 1,000,000

                }

            }

            return value;

        }

 

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            throw new NotImplementedException();

        }

    }

}

 

 

 

 

</Sample Code>

 

 

 

 

Amy Smart Sarah Wynter Jaime Pressly Ashanti Jennie Finch