WELCOME

This blog is where I post about my consulting work with Microsoft Technologies, and other random tidbits that don't fit in my Photo Blog or my Iraq Blog.

Wednesday, February 25, 2009

Why is my WPF Popup black and how do I get it positioned properly?

A quick WPF tip:

Problem: I was trying to create a cool OS X style semi-transparent round cornered popup but no combination of setting Background=Transparent or Opacity<1 would give me anything but a big square cornered black box in the wrong part or the screen.

Solution: You need to set the AllowsTransparency property on the Popup to True, and set the PlacementTarget and Placement properties to control the position the Popup opens in.


<Popup x:Name="RecipeSourcePopup"

               PlacementTarget="{Binding ElementName=MainStackPanel}"

               Placement="Center" AllowsTransparency="True"

               HorizontalAlignment="Center" VerticalAlignment="Center" >

Thursday, February 12, 2009

Email Management Tip: Automatically flagging sent email that requires a followup

Here's a great email management tip that I got from an "aunt" of mine:

How often do send an email that requires a response from somebody else, or that you want to followup on later? How often does the other person fail to reply? How often do you fail to remember to follow up?

So here's the tip: On any email that requires a followup, cc: it to YOURSELF and then create an Inbox rule in Outlook or filter in Gmail (I love Gmail) that saves the sent message to folder/label named "Followup Required".

Wala! An automagic task list!

And you can add tasks for yourself the same way... just email yourself a note... it doesn't have to be a reply.

And if you thought that was interesting you might like this old post on the rest of my email management strategy.

Wednesday, February 11, 2009

Great article on using: WCF in Silverlight 2

Here's a great article I just found on using WCF in Silverlight 2. It really should be at the top of any Google search remotely related to WCF and Silverlight and so here's a little link love to boost it up the list:

http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2

Friday, February 6, 2009

Applying (and blocking) global styles in WPF/Silverlight

I've been digging the ability to globally set default styles in a WPF/Silverlight application. For example I have a file named GlobalStyles.xaml that contains the default styles for all windows in my app:


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!--Default styles that will apply to any object of the specified type (if it doesn't have style set locally)-->

    <Style TargetType="Button">

        <Setter Property="FontSize" Value="11"/>

        <Setter Property="FontWeight" Value="UltraBold"/>

        <Setter Property="Button.Margin" Value="10,0,10,0" />

        <Setter Property="Button.Padding" Value="3"  />

        <Setter Property="Button.Height" Value="25" />

        <Setter Property="Button.MinWidth" Value="75" />

    </Style>

    <Style TargetType="Label" >

        <Setter Property="Margin" Value="10,0,10,0" />

        <Setter Property="FontSize" Value="11"/>

        <Setter Property="HorizontalAlignment" Value="Left"/>

        <Setter Property="VerticalAlignment" Value="Top"/>

        <Setter Property="MinWidth" Value="75"/>

    </Style>


This is all great EXCEPT when you DON'T want your groovy new global styles to apply to a window or specific element on your page. In my specific case the global style for "Button" was totally hosing the display of the WPFToolkit DataGrid which is itself composed of lots of WPF Buttons.

The answer is to put an EMPTY Style into the Resources section of the page or control that you want to block the global style from applying to. Here is the DataGrid specific example:


<toolkit:DataGrid.Resources>

    <!--The following line overrides (blocks) the global default styles

    for "Button" from effecting the datagrid -->

    <Style TargetType="Button" />

</toolkit:DataGrid.Resources>


You can do the same thing for the whole Window like this:


<Window.Resources>

        <Style TargetType="Button" />

</Window.Resources>

Wednesday, February 4, 2009

Simple Asynch Demo in Silverlight

Here's a demo that shows a very simple lambda and delegate based approach to making async calls in Silverlight.




Thanks to MichealGG for the code. See his response to my question on StackOverflow here: http://stackoverflow.com/questions/508177/implementing-a-nested-asynch-call-stack-scenario-in-net


<UserControl x:Class="SilverlightTestApp.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock Name="ResultsTextBlock"
Width="400" Height="300"
TextWrapping="Wrap"/>
</Grid>
</UserControl>




using System;

using System.Threading;

using System.Windows;

using System.Windows.Controls;

 

 

namespace SilverlightTestApp

{

    public partial class Page : UserControl

    {

        public Page()

        {

            InitializeComponent();

 

        }

 

        private void AsynchDemo()

        {

            ResultsTextBlock.Text = "";

            ResponseWriteLine("BEGIN: AsynchDemo()");

 

            AsyncHelp(

                () => SlowDateTime("The time is now:  "),

                ex => ResultsTextBlock.Text += ex.ToString(),

                bla => ResultsTextBlock.Text += bla.ToString()

                );

            ResponseWriteLine("CALLED: SlowDateTime()");

 

            Action<string> r = ResponseWrite;

 

            for(int x = 0;x<100;x++)

            {

                AsyncHelp(

                    () => RandomSleep(x),

                    ex => ResultsTextBlock.Text += ex.ToString(),

                    r);  //use a delegate instead of a lambda expression

            }

 

            ResponseWriteLine("END: RandomSleep() x 100");

        }

 

        public string RandomSleep(int input)

        {

            Random r = new Random();

            int t = r.Next(10000);

            Thread.Sleep(t);

            return input.ToString() + "."; ;

        }

 

        public void ResponseWrite<T>(T result)

        {

            ResultsTextBlock.Text += result.ToString();

        }

        public void ResponseWriteLine<T>(T result)

        {

            ResultsTextBlock.Text += result.ToString() + Environment.NewLine;

        }

 

        public string SlowDateTime(string text)

        {

 

            Thread.Sleep(5000);

            return text + DateTimeOffset.Now.ToString();

        }

 

        public void AsyncHelp<T>(Func<T> f, Action<Exception> econt, Action<T> cont)

        {

            var t = new Thread((_) =>

            {

                try

                {

                    var res = f();

                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => cont(res));

                }

                catch (Exception ex)

                {

                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => econt(ex));

                }

            });

            t.Start();

        }

 

        private void Button_Click(object sender, RoutedEventArgs e)

        {

            AsynchDemo();

        }

    }

}