Welcome to MSDN Blogs Sign in | Join | Help

Lester's WPF blog


Simple, easy & beautiful

News

XAML 2009 Features: Node Loop flexibility

 

[This is part of a series on New WPF\XAML Features] 

 

So by now most of you must have noticed the System.Xaml dll as part of your .NET 4 WPF projects. It’s a well componentized XAML stack that provides a lot of flexibility working with XAML. So at the core we a System.Xaml.XamlReader and XamlWriter which provide the base implementation and definition for a reader and writer. XamlXmlReader is a reader that reads in XAML and produces a XAML node stream. This stream is then consumed by a XamlXmlWriter to produce the object graph. Similarly for the Save path, you have the XamlObjectReader and XamlXmlWriter.

 

So the Load Path looks like

XAML  à XXR à Node Stream à XOW à Object Graph

 

The Save path would look like

Object Graph à XOR à Node Stream à XXW à XAML

 

Prior to .NET 4, you didn’t have access to the internals; the access points were XamlReader.Load and XamlWriter.Save in PresentationFramework. In .NET 4, we provide access to the node stream and you could manipulate this node loop. There are 7 XamlNodeType’s that you need to look out for in this node loop.

 

An example of a node loop could be filtering out events and unknown elements. Wouldn’t that make a nice feature in XamlPadX J..

 

The code below shows how we could replace the Window in the Xaml passed with a Page.

 

XmlReader xmlReader = XmlReader.Create(input);

XamlXmlReader reader = new XamlXmlReader(xmlReader, System.Windows.Markup.XamlReader.GetWpfSchemaContext());

XamlObjectWriter writer = new XamlObjectWriter(reader.SchemaContext);

 

while (reader.Read())

{

    switch (reader.NodeType)

    {

        case XamlNodeType.StartObject:

            if (!reader.Type.Name.Equals("Window"))

                writer.WriteNode(reader);

            else

                writer.WriteStartObject(new XamlType(typeof(Page), reader.SchemaContext));

            break;

 

        case XamlNodeType.EndObject:

        case XamlNodeType.StartMember:

        case XamlNodeType.EndMember:

        case XamlNodeType.Value:

        case XamlNodeType.GetObject:

        case XamlNodeType.NamespaceDeclaration:

            writer.WriteNode(reader);

            break;

    }

}

 

Attached is a project that shows how events\unknown elements could be filtered.

Share this post

 

New WPF Features: Full Trust Xbap Deployment

This is part of a series on New WPF Features 

In earlier versions, on trying to deploy a Full Trust Xbap, you would get a "Trust Not Granted" error. Its possible to workaround this issue by installing an assembly in the GAC that has the AllowPartiallyTrustedCallersAttribute. Another option is to install a certificate on the user machine and sign the Xbap with the certificate. Yeah, its painful and we worked on this issue for this release

Now on deployment, you would get a clickonce dialog so that the user can determine if s\he want to run the Xbap. This is really beneficial in the case of Intranet deployment. Do I hear a WOW.. :)

Below is the pictorial difference..

 

In addition, clicking on the More Information link open up a dialog with additional information that would enable the user to make a more knowledgeable decision about installation

Share this post

 

Xaml 2009 Features: Built in Types

In Xaml2009, we have built-in support for common CLR types which simplifies authoring. So rather than specifying something like

<s:String xmlns:s="clr-namespace:System;assembly=mscorlib"> Foo </s:String>

We can use the notation <x:String > Foo </s:String>

The list of types supported is below:

     <x:String>

     <x:Char>

     <x:Single>

     <x:Double>

     <x:Boolean>

     <x:Byte>

     <x:Int16>

     <x:Int32>

     <x:Int64>

     <x:Decimal>

     <x:Object>

     <x:Uri>

     <x:TimeSpan>

     <x:Array>

One thing to note is wrt WPF this will work only in loose Xaml. This means that these features cannot be used within Cider\Blend. Rob has a post clarifying the absence of tooling support.

Now you get the slight change in title J

[This is part of a series on New WPF\XAML Features] 

 

Share this post

 

New WPF Features: Bindable Run

This is part of a series on New WPF Features

Bindable run - yeah its possible currently but you would require a custom implementation. if you didnt like to create your own implementation, likely you would be using textblock. Problem here is that its likely you would have issues in copy paste scenarios, layout and what not. Now its a lot easier as the framework supports it.

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

           xmlns:sys="clr-namespace:System;assembly=System"

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

      <WrapPanel.Resources>

            <sys:String x:Key="string1">Hello world!! .NET 4 Coming Soon!! New features in WPF!!</sys:String>

      </WrapPanel.Resources>

      <FlowDocumentReader Width="350" BorderBrush="red" BorderThickness="3" Height="150">

            <FlowDocument>

                  <Paragraph>

                        <Run>Sample Text Beginning:</Run>

                        <TextBlock Text="{StaticResource string1}"></TextBlock>

                        <Run>End of sample text.</Run>

                  </Paragraph>

            </FlowDocument>

      </FlowDocumentReader>

      <FlowDocumentReader Width="350" BorderBrush="red" BorderThickness="3" Height="150">

            <FlowDocument>

                  <Paragraph>

                        <Run>Sample Text Beginning:</Run>

                        <Run Text="{StaticResource string1}" />

                        <Run>End of sample text.</Run>

                  </Paragraph>

            </FlowDocument>

      </FlowDocumentReader>

</WrapPanel>

 

Difference is obvious.. in the textblock case you have wider separations, text is clipped.... look to the right.. its perfect :)

 

 

Share this post

 

New WPF Features: Script Interop in Xbap

This is part of a series on New WPF Features

Often times you have Xbap hosted in a Html page and its pretty common to have some kind of interaction between the host and Xbap. In this release, we have enabled these scenarios.

 

Operation

Changes In

Code Sample

Invoking a function

Xbap

dynamic script = BrowserInteropHelper.HostScript;

              script.ReportProgress(progressValue.ToString());

 

Passing an object to a function

Script

function ReportDate(dateTime) {

    date = new Date(dateTime);

    var dateBox = document.getElementById("displayDate");

    dateBox.value = date.getFullYear();

}

 

 

Xbap

DateTime date1 = (DateTime)date.SelectedDate;

script.ReportDate(date1);

 

Fetching custom data from the script

Script

function ComplexData() {

    var res = { FirstName: "John", LastName:"Foo", Age:20 };

    return res;

}

 

 

Xbap

var result = script.ComplexData();

var resultName = result.FirstName;

var resultAge = result.Age;

tbData.Text = "FirstName: " + resultName + " Age: " + resultAge;

 

Fetch Function from the script

Script

function ReturnFunction() {

    return TestAdd;

}

 

function TestAdd(arg1, arg2) {

    return arg1 + arg2;

}

 

Xbap

var AddFunction = script.ReturnFunction();

var value = AddFunction.call(null, 5, 6);

tbData1.Text = "Total: " + value;

 

Setting up a default callback

Script

function SetClickHandler(handler) {

    btn1.onclick = handler;

}

 

 

Xbap

OnClickHandler handler1 = new OnClickHandler();                   

script.SetClickHandler(handler1);

 

[ComVisible(true)]

    public class OnClickHandler

    {

        [DispId(0)] // This makes it the object’s default member.

        public void Invoke()

        {

            MessageBox.Show("Default Invoke");

        }

}

 

Setting up a custom callback

Script

var XBAPCallback;

function SetCallback(callbackObj) {

    XBAPCallback = callbackObj;

    btn2.onclick = OnViewReportButtonClick;

}

 

function OnViewReportButtonClick() {

    date = new Date();

    XBAPCallback.Callback(date.getFullYear());

}

 

 

Xbap

OnClickHandler handler = new OnClickHandler();

handler.mainViewModel = this.DataContext;

script.SetCallback(handler);

 

[ComVisible(true)]

    public class OnClickHandler

    {

        public object mainViewModel;

 

         public void Callback(object arg)

        {

            ((MainViewModel)mainViewModel).MyText = "CallBack:" + arg.ToString();

        }

    };

 

 

 

A simple sample (love the simple part..) is attached to show the above in action.. Note that you'll need to enable scripts in the browser to get the sample working.

Also, you could look at the publish folder in order to play with the sample without building it.

Share this post

 

New WPF Features: Binding to Dynamic Objects

This is part of a series on New WPF Features

C# 4.0 allows creation of dynamic objects which is useful when you are interacting with dynamic languages. If you are unfamiliar with the dynamic concept take a quick look at this blog entry

So back to WPF. We support binding to dynamic objects.. woohoo... To begin with you need to create the dynamic object (see attached proj)

    <Window.Resources>

        <local:DynamicObjectClass x:Key="MyDynamicObject" />

    </Window.Resources>

    <StackPanel Name="BindPanel" DataContext="{StaticResource MyDynamicObject}">

        <TextBox Text="{Binding Path=A}"/>

        <TextBlock Text="{Binding Path=B.C}" />

        <TextBox  Text="{Binding Path=[(x:Int32)0]}"/>

 

In the loaded event , we can then set values

            dynamic dynamicObj = BindPanel.DataContext ;

            dynamicObj.A = "Simple Binding";

 

            dynamicObj.B = new DynamicObjectClass();

            dynamicObj.B.C = "Nested Prop Binding";

 

            dynamicObj.AddItem("item 0");

            dynamicObj[0] = "Indexer Binding";

 

Project Code attached

Share this post

 

New WPF Features: LayoutRounding

This is part of a series on New WPF Features

LayoutRounding - If you are familiar with Silverlight, this is nothing new. If you are unfamiliar with it, all it does is that it rounds up lengths..

Take for example the code below (hypothetical case) 

<Border Width="33.9111111" Height="80.11111" BorderBrush="Red" Margin="2.1222222" BorderThickness="3.955">
<
Border Width="15.3333333" Height="40.11111" BorderBrush="Black" Margin="2.3333333" BorderThickness="3.89898555"></Border>

The one on the left is a bit blurry due to the subpixel positioning and doesnt use LayoutRounding. The one on the left is rendered with LayoutRounding and has crisper lines.

The property to enable LayoutRounding is UseLayoutRounding="true" ... By default this is set to false (unlike SL)

You can also take a look at the MSDN documentation

Share this post

 

New WPF Features: Key\Gesture Binding

This is part of a series on New WPF Features

We got a lot of feedback to improve the way a developer could set binding to the input keys and modifiers. Earlier, the command property on the inputbinding class was not a Dependency property - so binding to it was out of question. Also it didnt inherit the datacontext of the parent. There are workarounds and most likely you would be doing something like the below as is done in the CoreMVVM libraries.

    <Window.Resources>

        <!-- Allows a KeyBinding to be associated with a command defined in the View Model  -->

        <c:CommandReference x:Key="ExitCommandReference" Command="{Binding ExitCommand}" />

    </Window.Resources>  

    <Window.InputBindings>

        <KeyBinding Key="X" Modifiers="Control" Command="{StaticResource ExitCommandReference}" />

    </Window.InputBindings>

However, now we have baked this in the framework so the experience is a lot better. InputBindings inherits from Freezable for the DataContext and exposes the commands as Dependency Properties. Now the above looks something like

    <Window.InputBindings>

        <!-- See above for the previous experience -->

        <KeyBinding Command="{Binding ExitCommand}" Key="X" Modifiers="Control"/>

    </Window.InputBindings>

 

Aint that sweet.. You could also bind the Key and Modifiers as below.

    <Window.InputBindings>

        <!-- See above for the previous experience -->

        <KeyBinding Command="{Binding ExitCommand}"

                        Key="{Binding ExitCommand.GestureKey}"

                        Modifiers="{Binding ExitCommand.GestureModifier}"/>

    </Window.InputBindings>

 

So whats the plumbing needed for this..

In your delegateCommand class, declare the following 3 properties:

        public Key GestureKey { get; set; }

        public ModifierKeys GestureModifier { get; set; }

        public MouseAction MouseGesture { get; set; }

 

Now in the ViewModel, set these properties when you initialize the command

        public ICommand ExitCommand

        {

            get

            {

                if (exitCommand == null)

                {

                    exitCommand = new DelegateCommand(Exit);

                    exitCommand.GestureKey = Key.X;

                    exitCommand.GestureModifier = ModifierKeys.Control;

                    exitCommand.MouseGesture = MouseAction.LeftDoubleClick;

                }

                return exitCommand;

            }

        }

 

Thats it... the sample code is attached.

 

 

Share this post

 

New WPF Features: ClearTypeHint

This is part of a series on New WPF Features

WPF enforces grayscale rendering when text is rendered on a transparent area. However, its possible that the background of a control is opaque even though its inside a transparent area. For example, popups have rounded edges and will have the allowstransparency property set. Same is the case with transparent windows.

Now in .NET 4, we provide the developer to decide whether to render with cleartype or not. The way to do this is to set the RenderOptions.ClearTypeHint property.

RenderOptions.ClearTypeHint="Enabled"

This forces the rendering engine to enable Cleartype for the subtree. Intermediate render targets, such as Effect, OpacityMask, VisualBrush, DrawingBrush, Clip, and Opacity, can introduce backgrounds that are not fully opaque. WPF disables ClearType when it detects that the buffer into which text is drawn could have a transparent background. However, you could easily enable it again.

To get a more clear picture, consider the XAML like

 <Window AllowsTransparency="True" WindowStyle="None" RenderOptions.ClearTypeHint="Enabled">

      <StackPanel>

            <TextBlock Name="Block1">This text will be rendered with ClearType.</TextBlock>

            <TextBlock Opacity="0.9" Name="Block2" >

                 This text will be rendered with NO ClearType (note the opacity Prop).

            </TextBlock>

            <Grid Height="100" Background="White" >

                  <Grid.Clip>

                        <EllipseGeometry RadiusX="300"     RadiusY="200"      Center="150,120"/>

                  </Grid.Clip>                 

                  <Grid.RowDefinitions><RowDefinition/><RowDefinition/></Grid.RowDefinitions>

                  <TextBlock Name="Block3" >    This text will be rendered with NO ClearType.</TextBlock>

                  <TextBlock Name="Block4"  Grid.Row="1" RenderOptions.ClearTypeHint="Enabled">

                      This text will be rendered with ClearType

                  </TextBlock>

            </Grid>

            <TextBlock Name="Block5">This text will be rendered with ClearType.</TextBlock>

      </StackPanel>

</Window>

 

Here the values are set as per the hierarchy

Window à hint enabled

                StackPanel à inherits Hint (cleartype)

                                Block1 à inherits Hint (cleartype)

                                Block2 à overrides Hint because of Opacity [intermediate render target]

                                Grid à overrides Hint because of Clip [intermediate render target]

                                                Block3 à Inherits Grid’s hint (No cleartype)

                                                Block4 à overrides Hint to enabled (Cleartype)

 

 

Share this post

 

New WPF Features: CaretBrush\SelectionBrush

This is part of a series on New WPF Features

There have been quite a few asks for changing the selection color and the caret color. We have now provide 2 properties to make this possible

  • CaretBrush
  • SelectionBrush  

An example usage would be like

  • SelectionBrush="RED"
  • SelectionOpacity="0.3"  (Default value is 0.6)
  • CaretBrush="Red"

 

These properties are avaialble on controls that allow selection\caret.

Share this post

 

New WPF Features: Custom Speller Dictionary

This is part of a series on New WPF Features

In previous versions, adding a custom dictionary was an unsupported scenario. You could still do it but it required writing a bunch of code.

In this release, we have provided suport for adding custom dictionaries.

     <RichTextBox FontSize="24" SpellCheck.IsEnabled="true" >

            <SpellCheck.CustomDictionaries>

                  <sys:Uri>Dictionary1.lex</sys:Uri>

                  <sys1:Uri>\\dictServer\Dictionary3.txt</sys1:Uri>          

            </SpellCheck.CustomDictionaries>

            <FlowDocument>

                  <Paragraph>Some Names: Zorig Lester </Paragraph>

                  <Paragraph>Misspelled: Zorg BlahBlah </Paragraph>

            </FlowDocument>

      </RichTextBox>

The dictionaries are plain text files and list the words to be updated.

For a non default locale (en-us) you can specify the locale ID at the top (#LID localeID). In the pic above, we are using the locale 2057 which corresponds to english-UK.

 

Share this post

 

New WPF Features: Jumplists

This is part of a series on New WPF Features

Jumplists is a feature of Win7 where in you can the context menu is richer than the usual close\restore options. WPF provides a managed API to work with these features in Win7.

Now that we have seen how it looks like, lets look at how its created [Thanks to Andre for the initial code :) ]

Setting up the jumplist is simple and API is really easy for addition\deletion of items

            JumpList jumpList = new JumpList();

            JumpList.SetJumpList(Application.Current, jumpList);

 

            JumpTask jumpTask = new JumpTask();

            jumpTask.Title = jumpTask.Description = namesToUse[0];

            jumpTask.CustomCategory = "DocumentApps";

            jumpTask.ApplicationPath = "notepad.exe";

            jumpList.JumpItems.Add(jumpTask);

 

            jumpList.Apply();

Now for setting up those buttons at the bottom of the Preview image

<Window.TaskbarItemInfo>

       <TaskbarItemInfo

           Description="My TaskbarItemInfo"

           Overlay="..\Resources\powerButton.ico">

            <TaskbarItemInfo.ThumbButtonInfos>

                <ThumbButtonInfo

                    Command="Cut"

                    CommandTarget="{Binding ElementName=textBox}"

                    Description="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"

                    DismissWhenClicked="False"

                    ImageSource="..\Resources\cut.png" />

 

Clicking on the buttons Dismiss the previewpane by default. Overlay allows you to place another image as seen in the taskbar (powerbutton icon overlays the shield)

The code for the sample is attached 

 

Share this post

 

New WPF Features: Easing Functions

This is part of a series on New WPF Features

Easing functions enables adding custom math formulas to your animations. The animations also looks more realistic and smoother. WPF now provides this functionality and as in SL there are 11 such inbuilt functions. Each of these come with 2 Easing Modes - EaseIn,EaseOut,EaseInOut.                                                                               

The functions for the EaseIn Mode are shown below.

        <BackEase Amplitude='1' EasingMode='EaseIn' />

        <BounceEase Bounces='3' Bounciness='2' EasingMode='EaseIn'/>

        <CircleEase  EasingMode='EaseIn' />

        <CubicEase  EasingMode='EaseIn' />

        <ElasticEase  EasingMode='EaseIn' Oscillations='3' Springiness='3' />

        <ExponentialEase  EasingMode='EaseIn' />

        <PowerEase  EasingMode='EaseIn' Power='3'/>

        <QuadraticEase  EasingMode='EaseIn' />

        <QuarticEase  EasingMode='EaseIn' />

        <QuinticEase  EasingMode='EaseIn' />

        <SineEase  EasingMode='EaseIn' />

 

 I tried the different functions in a sample (graph code by our dev Brandon). The code is attached

 

 

Share this post

 

New WPF Features: TextFormattingMode for clear text

This is part of a series on New WPF Features

Now there has been feedback since 3.0 that the WPF text doesnt render clearly when the fontsizes are smaller. So for .NET 4 we forked on this issue and fixed it by introducind the property TextOptions.TextFormattingMode. The default value is ideal which is what we have currently. The other option is Display and it makes small text look crisper and clear.

Lets see it in action

<StackPanel xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'

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

            <TextBox TextOptions.TextFormattingMode="Ideal" FontSize="10">HELLO WORLD</TextBox>

            <TextBox TextOptions.TextFormattingMode="Display" FontSize="10">HELLO WORLD</TextBox>

           

            <TextBox TextOptions.TextFormattingMode="Ideal" FontSize="15">HELLO WORLD</TextBox>

            <TextBox TextOptions.TextFormattingMode="Display" FontSize="15">HELLO WORLD</TextBox>

</StackPanel>

See the difference :) ... also for asian characters the difference is very evident ..

Guidelines for this property 

Scenarios

Recommended Mode

Large Text (15pt+)

Ideal \ Display (users preference)

Transformed Text

Ideal

Zoomed Text

Ideal

Design Scenarios

Ideal

Small Text

Display

Share this post

 

VS 2010\.NET 4 Beta2 available for download

Visual Studio 2010 and .NET Framework 4 Beta 2 will be available to MSDN subscribers, with general availability on October 21.

The official launch of Visual Studio 2010 and .NET Framework 4 is March 22, 2010.

For info about packaging, pricing, and licensing take a look at the new VisualStudio site

Share this post

 

More Posts Next page »
Page view tracker