Creating transparent buttons, panels and other control with Compact Framework and putting one into other

In WPF/Silverlight world it's very simple to make transparent controls and put anything inside anything. However, that's not the situation in WinForms, and even worth in the world of compact devices with CF. Within this worlds, there is only one way to make controls transparent - to use color masks. Today, we'll create transparent controls with Compact Framework and put it into panel, which has image background.

image

So let's start. First of all, we need create our own control. For this purpose, we have to inherit from Control and override couple of things. More precise: OnPaint and OnPaintBackground. We do not want to paint background for transparent control, so let's prevent it.

public class TransparentImageButton : Control

protected override void OnPaintBackground(PaintEventArgs e) {
           //prevent
       }

       protected override void OnPaint(PaintEventArgs e) {

Next, we have to get graphics, delivered by OnPain event argument and draw our image over it. However, BitBlt (which is used by core graphics system) is not very fast method, so it's better for us to draw everything first and then copy final image to the device.

Graphics gxOff;
Rectangle imgRect;
var image = (_isPressed && PressedImage != null) ? PressedImage : Image;

if (_imgOffscreen == null) {
_imgOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
}

gxOff = Graphics.FromImage(_imgOffscreen);
gxOff.Clear(this.BackColor); 
...
         

if (image != null) {
var imageLeft = (this.Width - image.Width) / 2;
var imageTop = (this.Height - image.Height) / 2;

if (!_isPressed) imgRect = new Rectangle(imageLeft, imageTop, image.Width, image.Height);
else imgRect = new Rectangle(imageLeft + 1, imageTop + 1, image.Width, image.Height);
var imageAttr = new ImageAttributes();

To make images transparent, we have to use (as mentioned earlier) transparency color key (to tell windows what color it should not draw. We can code or provide this value to detect it by hitting any pixel on the image. Just like this:

public static Color BackgroundImageColor(this Bitmap bmp) {
           return bmp.GetPixel(0, 0);
       }

Now we can keep working.

imageAttr.SetColorKey(image.BackgroundImageColor(), image.BackgroundImageColor());
gxOff.DrawImage(image, imgRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imageAttr);
} if (_isPressed) {
var rc = this.ClientRectangle;
  rc.Width--;
  rc.Height--;
  gxOff.DrawRectangle(new Pen(Color.Black), rc);
}
e.Graphics.DrawImage(_imgOffscreen, 0, 0);

Also, we have to provide others with possibility to handle this even too, thus we will not forget to add base.OnPaint(e); at  the end.

Next step is to detect whether our button is clicked or not. We'll override keyboard and mouse events to detect this.

protected override void OnKeyDown(KeyEventArgs e) {
            _isPressed = this.Focused; this.Invalidate();
            base.OnKeyDown(e);
        }

        protected override void OnKeyUp(KeyEventArgs e) {
            _isPressed = false; this.Invalidate();
            base.OnKeyUp(e);
        }

        protected override void OnMouseDown(MouseEventArgs e) {
            _isPressed = this.Focused; this.Invalidate();
            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e) {
            _isPressed = false; this.Invalidate();
            base.OnMouseUp(e);
        }

Compile and run to see no problem, when our transparent button lies on solid color control, however, we want to put it into panel with background - just like this one. In this case, you can use real transparent PNG and GIF images, also you can replace transparent color with well known Magenta (or any other color).

public class ImagePanel : Panel {

        public Bitmap Image { get; set; }

        protected override void OnPaintBackground(PaintEventArgs e) {
            e.Graphics.DrawImage(Image, 0, 0);
        }
    }

When we'll put it onto anything, that has no background color, we'll see that our "fake transparency" disappears. Why this happen? To provide transparency Windows uses color masks, also while confederating facts, clipping algorithm within GDI is not very trustful, thus the only thing can be taken into account is color. But what to do if we have an image? We should clip it manually. We cannot just get the handle to parent device surface (see above about trustful GDI), so the only way to do it is by providing something, that we know for sure. For example interface, telling us, that parent has image, which drawn on the screen.

internal interface IHaveImage {
        Bitmap Image { get; set; }
    }

When we know it, all we have to do is to clip the region of this image (not device context) and draw it as part of our really transparent control.

if (this.Parent is IHaveImage) {
                var par = this.Parent as IHaveImage;
                gxOff.DrawImage(par.Image.Clip(this.Bounds), 0, 0);
            }

The implementation of Image.Clip is very straight forward.

public static Bitmap GetSS(this Graphics grx, Rectangle bounds) {
    var res = new Bitmap(bounds.Width, bounds.Height);
    var gxc = Graphics.FromImage(res);
    IntPtr hdc = grx.GetHdc();
    PlatformAPI.BitBlt(gxc.GetHdc(), 0, 0, bounds.Width, bounds.Height, hdc, bounds.Left, bounds.Top, PlatformAPI.SRCCOPY);
    grx.ReleaseHdc(hdc);
    return res;
}

public static Bitmap Clip(this Bitmap source, Rectangle bounds) {
    var grx = Graphics.FromImage(source);
    return grx.GetSS(bounds);
}

We done. Compiling all together will fake transparency for controls, even when it's parents background is not pained with  solid color brush.

Source code for this article

P.S. Do not even try to inherit your custom Button control from framework Button class, dev team "forgot" to expose it's event for override. So, OnPaint, OnPaintBackground, OnKeyUp, OnKeydown, OnMouseUp and OnMouseDown aside with most of other base events will not work for you, also BaseButton class has no default constructor, so the only class you can inherit from is Control.

Have a nice day and be good people.

x-posted from http://blogs.microsoft.co.il/blogs/tamir
How to P/Invoke VarArgs (variable arguments) in C#? ... or hidden junk in CLR

Recently I wrote a cheat sheet for pinvoking in .NET. Shortly after I got a question in comments about how to deal with variable arguments, when it's more, then one parameter. Also what to do if those arguments are heterogeneous?

Let's say, that we have following method in C:

int VarSum(int nargs, ...){
    va_list argp;
    va_start( argp, nargs );
    int sum = 0;
    for( int i = 0 ; i < nargs; i++ ) {
        int arg = va_arg( argp, int );
        sum += arg;
    }
    va_end( argp );

    return sum;
}

We can expose this method to C# as following:

[System.Runtime.InteropServices.DllImportAttribute("unmanaged.dll", EntryPoint = "VarSum")]
        public static extern int VarSum(int nargs,int arg1);

[System.Runtime.InteropServices.DllImportAttribute("unmanaged.dll", EntryPoint = "VarSum")]
        public static extern int VarSum(int nargs,int arg1,int arg2);

[System.Runtime.InteropServices.DllImportAttribute("unmanaged.dll", EntryPoint = "VarSum")]
        public static extern int VarSum(int nargs,int arg1,int arg2,int arg3);

etc...

And it will work. However, if you'll try to expose it as int array, marshaller will fail to understand how to align things

[System.Runtime.InteropServices.DllImportAttribute("unmanaged.dll", EntryPoint = "VarSum")]
        public static extern int VarSum(int nargs,int[] arg);

This in spite of the fact, that this method will work properly with another signature

int ArrSum(int* nargs) {
    int sum = 0;
    for( int i = 0 ; i < 2; i++ ) {
        sum += nargs[i];
    }
    return sum;
}

So what to do? The official answer is - you have nothing to do, rather then override all possibilities. This is very bad and absolutely not flexible. So, there is small class in C#, named ArgIterator. This one is similar to params object[], but knows to marshal into varargs. The problem is, that you have no way to add things inside. It's "kind-of-read-only".

Let's look into reflected version of ArgIterator. We'll see there something, named __arglist and __refvalue. OMG, isn't it good old stuff similar to "__declspec(dllexport) int _stdcall" etc.? It is! But can we use it in C#? We can! Just sign your method as Cdecl and you have working signature for "..."

[System.Runtime.InteropServices.DllImportAttribute("unmanaged.dll", EntryPoint = "VarSum",
            CallingConvention=System.Runtime.InteropServices.CallingConvention.Cdecl)]
        public static extern int VarSum(int nargs, __arglist);

Yes, looks strange, and absolutely not CLR compliant. However, this is the only way to expose varargs to CLR via P/Invoke. How to use it? Simple:

c = VarSum(2, __arglist(5, 10));

Have a nice day and be good people. Also, my question to Microsoft is why this stuff is not in MSDN and we, as developers, have no way to get rid of it.

Is not it very good practices to use non-compliant methods? Give us another way to do it!
Is not it very good practices to use variable arguments in unmanaged method signatures? So why you want dynamic types in C# 4?

Source code for this article

x-posted from http://blogs.microsoft.co.il/blogs/tamir
Asus R50A UMPC review

So, I got new branded Asus R50A UMPC for test. This ultra mobile machine with 5.6" WSVGA (1024x768) screen, based on Intel US15W chipset, comes with Intel Atom Z520 (1.33 Ghz, 533Mhz) processor, 1Gb of RAM and 20GB SSD. Also it has 3.5G mobile unit, integrated 802.11b/g network card and GPS. First impression was very cool. Slick design, big screen build in fingerprint reader.

 

What in the box? Power adapter (110/220V), compact keyboard, bunch of cables, extra stilus and handling strap.

What else this machine has? Microcard reader, three mini-usb sockets, one regular USB and camera. Looks like pretty fine machine, but not for $2K+ price tag. But who cares when we buy real good gadget? However, my euphoria disappears during 6 minutes startup (this was not first startup - first took more, then 15 minutes).

It was preinstalled with Windows Vista SP1 Ultimate (for this tiny machine) aside with huge amount of Asus junkware, so it was was even unable even to calculate Vista experience score

Also it has no drivers for strange device, named "Mini Card" (with factory branded Asus OS installation)

Well, it's probably because I'm still not connected to internet... Let's connect office WiFi... Err... It has some troubles with wireless network discovery - 2 bars for 12 feet distance from access point (my W500 has all 5) and no other networks (with 4 and less bars on another machine). Let's connect it. Hm, "unable to connect"... Weird. Leave it by now. This is multimedia device, so, probably, video will play better? Well, it failed also with playback of Windows sample movie. So maybe it has great battery life? Not really. Without doing anything new 2 cells, 2600mAh battery enough for less, then two hours (with vista battery saver it extended to 3, while this device does not support aero interface).

But the final accord was this one (one again - this is branded Asus installation):

 image

Bottom line: 0/5. I paid $360 for my wife's pink Acer Aspire One and got much better computer (it even has camera).

image

The only thing remains enigma for me is why, the hell, this piece of crap costs more, then $2500?

Have a nice day and be good people - do not buy this machine!

x-posted from http://blogs.microsoft.co.il/blogs/tamir
Auto scroll ListBox in WPF

In WinForms era it was very simple to autoscroll listbox content in order to select last or newly added item. It become a bit complicated in WPF. However, complicated does not mean impossible.

image

As for me, Microsoft should add this feature to base ListBox implementation as another attempt to be attractive environment for LOB application. See, for example this thread from MSDN forums. I'm really understand this guy. He do not want to implement it with a lot of code, he just want it to be included in core WPF control (but he should mark answers)

Generally, the simplest way to it is by using attached properties. So, your code will look like this

<ListBox Height="200" l:SelectorExtenders.IsAutoscroll="true" IsSynchronizedWithCurrentItem="True" Name="list"/>

But what's going on under the hoods? There it bit complicated :) First of all, we should create attached property, named IsAutoscroll

public class SelectorExtenders : DependencyObject {

        public static bool GetIsAutoscroll(DependencyObject obj) {
            return (bool)obj.GetValue(IsAutoscrollProperty);
        }

        public static void SetIsAutoscroll(DependencyObject obj, bool value) {
            obj.SetValue(IsAutoscrollProperty, value);
        }

        public static readonly DependencyProperty IsAutoscrollProperty =
            DependencyProperty.RegisterAttached("IsAutoscroll", typeof(bool), typeof(SelectorExtenders), new UIPropertyMetadata(default(bool),OnIsAutoscrollChanged));

now handle it when you set it's value by handling new items arrivals, set current and then scroll into it

public static void OnIsAutoscrollChanged(DependencyObject s, DependencyPropertyChangedEventArgs e) {
            var val = (bool)e.NewValue;
            var lb = s as ListBox;
            var ic = lb.Items;
            var data = ic.SourceCollection as INotifyCollectionChanged;

            var autoscroller = new System.Collections.Specialized.NotifyCollectionChangedEventHandler(
                (s1, e1) => {
                    object selectedItem = default(object);
                    switch (e1.Action) {
                        case NotifyCollectionChangedAction.Add:
                        case NotifyCollectionChangedAction.Move: selectedItem = e1.NewItems[e1.NewItems.Count - 1]; break;
                        case NotifyCollectionChangedAction.Remove: if (ic.Count < e1.OldStartingIndex) { selectedItem = ic[e1.OldStartingIndex - 1]; } else if (ic.Count > 0) selectedItem = ic[0]; break;
                        case NotifyCollectionChangedAction.Reset: if (ic.Count > 0) selectedItem = ic[0]; break;
                    }

                    if (selectedItem != default(object)) {
                        ic.MoveCurrentTo(selectedItem);
                        lb.ScrollIntoView(selectedItem);
                    }
                });

            if (val) data.CollectionChanged += autoscroller; 
            else  data.CollectionChanged -= autoscroller;

        }

That's all. Also it can be done by visual tree querying (as thread started proposed). Find scrollviewer inside the ListBox visual tree and then invoke "ScrollToEnd" method of it.

Have a nice day and be good people. And, yes, WPF development team should consider this feature implemented internally for any Selector and ScrollViewer control

Source code for this article

x-posted from http://blogs.microsoft.co.il/blogs/tamir
Programming for Windows 7

Well, Windows 7 is going to be released by the end of next year. This is great news, because it seemed, that Microsoft finally understand how to get the best of Windows Vista and make it to work not only on monster machines.

image

It even works on new brandy my wife's pinky machine. And if it works there and my wife is happy with it, this OS going to be very impressive.

image

But from the other hand, we, as developers should be ready today to developer Windows 7 ready application (by the way, Vista Battery Saver works for Windows 7 as well as for Windows Vista, in spite of the fact, that power management in Windows 7 was improved dramatically). So let's start!

First thing we need is to read big Windows 7 Developer Guide. This document will explain most of new features for developers to build applications right. What is includes?

Windows Driver Kit (WDK) 3.0

Basically, Windows 7 works with Vista drivers, however, hibernation, power management, networking, PREfast will work much better. You also will have new WMI access for reliability monitors and ACPI.

Management and deployment

By default Windows 7 uses PowerShell 2.0 and Windows Installer. For PowerShell it includes enhanced cmdlets to manage Active Directory, IIS, etc. For Windows Installer, you finally can build "chainers" by yourself (the same approach, used for latest deployment of Microsoft products such as Silverlight, Visual Studio 2008 SP1 etc.) Also, you can get advantage by using Windows Filtering Platform (Firewall) and User Account Control (UAC) from inside your application by using new APIs.

Performance

The most significant change in Windows 7 for end-user point of view is improved performance. Windows 7 kernel is much smaller, that kernel of Windows Vista. Also it uses specific patterns to decrease background activities on low power, based on system triggers. New user-mode and kernel-mode APIs are used by Windows Drivers Foundation much more efficiently. Also system services are much smarter. For example, DCIA starts only when you connect new hardware. After drivers were installed the service shuts down. The same approach used by domain join, GP changes, new IP fetching etc. Windows 7 knows to run and stop services, based on system events, which decreases average work load and enhances whole system performance.

Multi-touch gestures and Interia API and used interface in general

Yes, you can use this API for your applications. Finally we can have more, then just mouse. And it is not only about multiple mouse devices. We can use single finder panning, raw touch input data, internal multitouch ink recognition, which is also supports math. Also it uses build-in MathML export feature.

There are a lot of other enhancements, such as smart bars, windows' stacking, gadget desktop (it does not eat battery as external process anymore), system ribbon menu integration. etc

Graphics

Direct 11, new Direct2D, DirectWrite (we can turn text anti-aliasing for small fonts, hurrah!), improved WIC, DX/GDI interoperability on system level with automatic fallback for weak hardware (yes, you should not be worry about it anymore). Also new video and audio format support with human readable interfaces. Yes, no more DirectDraw hacks. We can use new high level interfaces such as MFPlay to manage playbacks, Source Reader for decoding, Sink Writer for transcoders and re-coding compressions.

Web and communication

WCF is inside, as well as distributed routing table for peer-to-peer operations. BranchCache - new technology to reduce WAN traffic and latency.

Also Windows 7 is compatible with OpenSearch (I told, that Microsoft does not know to build search engines). Sharepoint integration and environment sensors platform, that can be used either for desktop and web applications.

There are much more features, that makes Windows 7 to pretend to be very good operation system. If you want to learn more about all those Windows 7 new features, I highly advice you to download and read this document. It includes most of new features of new OS with explanations and screenshots to make your learn and understand what can your future application do with all those new features.

Have a nice day and be good people.

BTW, if you have PDC version of Windows 7 and want to unlock it for using of some cool features, introduced during keynotes, it worth to visit here and learn how to :)

Download Windows 7 Developer Guide and start programming.

x-posted from http://blogs.microsoft.co.il/blogs/tamir
P/Invoke cheat sheet

I’m working a lot with p/invoke, and know how it’s hard to produce correct signature for unmanaged method. So, today I decided to publish basic cheat sheet for methods, parameters and attributes you should use in order to invoke unmanaged methods from managed code without a lot of problems. We start with data type translations. Here the table to understand it.

Data type from unmanaged signature Data type in managed signature
int int

the same with all other simple types such as double, uint, etc or private objects
void* IntPtr
int* ref int

the same with all other simple types such as double, uint, etc or private objects
char** ref IntPtr

later, you should get ascii string by using System.Runtime.InteropServices.Marshal.PtrToStringAnsi() method
wcar_t** ref IntPtr

later, you should get ascii string by using System.Runtime.InteropServices.Marshal.PtrToStringUni() method
const int* ref int
const char* [System.Runtime.InteropServices.In()] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string
(variable argument) [System.Runtime.InteropServices.In()] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.AsAny)] object

You can use either System.Runtime.InteropServices.In or System.Runtime.InteropServices.Out attribute to specify how arguments should be used.

Now we done with simple arguments, let’s see what can be done when argument is actually callback or delegate?

Unmanaged definition Managed definition
typedef void (*MyCallback)(int Arg)

[System.Runtime.InteropServices.UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]delegate void MyCallback(int Arg)
Caller cleans stack argument is used to assure, that we can call varargs type function, usually used by API provider. It is very similar to C# overrides for methods. Also you can use StdCall (this is default), ThisCall – stores this first and pushes other parameters on the stack, FastCall – not very supported :(

 

To call all those methods, we should know managed equivalents of unmanaged types. Here the table. The rule is simple – know how many bytes unmanaged type has and find managed type with the same number of bytes. Other words, you can marshal int into IntPtr too…

Unmanaged type Managed equivalent
bool bool
char sbyte (signed), byte (unsigned)
wchar_t char
double double
float single
int, long (signed) Int32
int, long (unsigned) UInt32
__int64 (signed) Int64
__int64 UInt64
short (signed) Int16
short (unsigned) UInt16
void void

But not only types are problem in managed/unmanaged transitions. Also structures are aligned differently. For this purpose we can use StructLayout attribute. Even if unmanaged classes are sequential and you used correct managed data types, you can find you with problems in Pack. What “pack” is? Pack is actually slot size in bytes for members of your structure. It can be 0, 1, 2, 4, 8, 16, 32, 64, or 128 and depends on the platform and application setting.

Now you can see, that it is not very complicated to create managed signatures when you have header of unmanaged assemblies. So go ahead and ask, if I missed something.

That’s all by now. Have a nice day and be good people.

x-posted from http://blogs.microsoft.co.il/blogs/tamir
Set binding, based on trigger

Let’s say, that you want to set binding. However, you want to set it by using some trigger. Wait! Why I need it? Let’s say, that I have some very special object, that actually has no hard-coded properties. All it’s properties are created during the runtime, based on some trigger. In this case, I still want to use binding, however, if the property does not exists, I cannot do it. In this special case (that we’ll probably speak more later), we can use this class – TriggerBinding.

How to do it? How to extend build-in binding and add such functionality? Simple. All we need is to write custom markup extension. So, we’ll create new one

public class TriggerBindingExtension : MarkupExtension

And expose all regular binding properties + three custom – TriggerSource, TriggerSourceName and Trigger itself

public IValueConverter Converter { get; set; }
public object ConverterParameter { get; set; }
public string ElementName { get; set; }
public RelativeSource RelativeSource { get; set; }
public object Source { get; set; }
public string TriggerSourceName { get; set; }
public UIElement TriggerSource { get; set; }
[TypeConverter(typeof(RoutedEventConverter))]
public RoutedEvent Trigger { get; set; }
public bool ValidatesOnDataErrors { get; set; }
public bool ValidatesOnExceptions { get; set; }
public string StringFormat { get; set; }
[TypeConverter(typeof(EnumConverter))]
public BindingMode Mode { get; set; }
[TypeConverter(typeof(PropertyPathConverter))]
public PropertyPath Path { get; set; }
[TypeConverter(typeof(BooleanConverter))]
public bool IsAsync { get; set; }
public string XPath { get; set; }
[TypeConverter(typeof(CultureInfoIetfLanguageTagConverter))]
public CultureInfo ConverterCulture { get; set; }

Next step is to override ProvideValue method of MarkupExtension and create the actual binding. We still do not want to bind it to any property

public override sealed object ProvideValue(IServiceProvider serviceProvider) {
        var _valueProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
        if (_valueProvider != null) {
           var _bindingTarget = _valueProvider.TargetObject as FrameworkElement;
           var _bindingProperty = _valueProvider.TargetProperty as DependencyProperty;
           var _binding = new Binding();
           _binding.Path = Path;
           _binding.XPath = XPath;
           _binding.Mode = Mode;
           _binding.Converter = Converter;
           _binding.ConverterCulture = ConverterCulture;
           _binding.ConverterParameter = ConverterParameter;
           _binding.IsAsync = IsAsync;
           if (ElementName != null) _binding.ElementName = ElementName;
           if (RelativeSource != null) _binding.RelativeSource = RelativeSource;
           if (Source != null) _binding.Source = Source;
           _binding.ValidatesOnDataErrors = ValidatesOnDataErrors;
           _binding.ValidatesOnExceptions = ValidatesOnExceptions;
           _binding.StringFormat = StringFormat;

Now, if we have TriggerSource and Trigger, everything fine, we can set subscribe to the trigger event and wire binding in the handler

private RoutedEventHandler _bindigHandler;

private void _registerHandler(FrameworkElement bindingTarget, DependencyProperty bindingProperty, Binding binding) {
   if (_bindigHandler == default(RoutedEventHandler)) {
      _bindigHandler = (RoutedEventHandler)(delegate {
         var _oldValue = bindingTarget.GetValue(bindingProperty);
         bindingTarget.SetBinding(bindingProperty, binding);
         if (_oldValue != bindingProperty.DefaultMetadata.DefaultValue) {
            bindingTarget.SetValue(bindingProperty, _oldValue);
            BindingOperations.GetBindingExpression(bindingTarget, bindingProperty).UpdateSource();
         }
      });
      TriggerSource = TriggerSource ?? bindingTarget;
      if (Trigger != null && TriggerSource != null) {
         TriggerSource.AddHandler(Trigger, _bindigHandler);
      } else {
         _bindigHandler.Invoke(this, null);
      }
   }
}

However, we also want to be able to seek Logical tree and find trigger source by it’s name. Let’s say this way

<TextBox Name="one" Text="{l:TriggerBinding ElementName=two, Path=Text, Mode=TwoWay, TriggerSourceName=three, Trigger=Button.Click}"/>
<TextBox Name="two"/>
<Button Name="three" Content="Click to trigger binding"/>

What’s the problem? We also have FrameworkElement.FindName method and LogicalTreeHelper.FindLogicalNode. But wait, in our case, when TextBox “one” is initialized, we still have no Button “three”, so we have to wait until the root element of TextBox will be fully loaded and then try to find logical node. For this purpose, we have very useful extended method

public static DependencyObject GetRoot(this DependencyObject current) {
         var _root = current;
         do { _root = LogicalTreeHelper.GetParent(_root); if (_root != null) current = _root; } while (_root != null);
         return current;
      }

So, all we have to do is to subscribe to Loaded event of the root and then wire the trigger for set binding

if (!string.IsNullOrEmpty(TriggerSourceName)) {
   var _root = _bindingTarget.GetRoot() as FrameworkElement;
   _root.Loaded += delegate {
      TriggerSource = LogicalTreeHelper.FindLogicalNode(_root, TriggerSourceName) as UIElement;
      _registerHandler(_bindingTarget, _bindingProperty, _binding);
   };
} else { _registerHandler(_bindingTarget, _bindingProperty, _binding); }

We done. Have a good day and be good people.

BTW, it’s also possible to postpone binding by using timer. Paul Stovell has very good sample of how to perform it.

Source code for this article

x-posted from http://blogs.microsoft.co.il/blogs/tamir
Issues, you reported were fixed

Hi, folks. And thank you for reporting issues with WpfPerf Performance Profiling tool. Now it was fixed, so, download and use new and fixed version.

Keep reporting, as you can see, you have the power to change!

image

Imaginary by Malcolm Dare

x-posted from http://blogs.microsoft.co.il/blogs/tamir
Silverlight Bidi Controls Library RC0 and movement from Beta 2 to RC0

Finally, I got free minute to convert Silverlight BiDi controls from Silverlight beta 2 to RC0 (you can download SL rc0 tools for VS2008 here) and as usual some breaking changes (the full list is here)

  • Calendar and DatePicker moved from System.Windows.Controls.Extended into System.Windows.Controls – Extended namespace is now deprecated.
  • CalendarButton is not inside System.Windows.Controls.Primitives
  • TypeConverter.CanConvertFrom(Type sourceType) was changed and now it has new first parameter ITypeDescriptorContext context
  • TypeConverter.CanConvertFrom(object value) was changed and now it has new first parameter ITypeDescriptorContext context and second parameter System.Globalization.CultureInfo culture
  • TypeConverter.ConvertFromString is not virtual anymore
  • TextDecorationCollectionConverter was removed
  • generic.xaml should be placed into themes directory (as in WPF)
  • VisualTransition.Duration is not VisualTransition.GeneratedDuration
  • ContentPresenter has no HorizontalContentAlignment and VerticalContentAlignment. It has HorizontalAlignment and VerticalAlignment now. Also it has no Background, Padding,TextAlignment,TextDecorations and TextWrapping properties

Those, basically, all changes done in Silverlight RTL support library. So, you can download and use the latest version within Silverlight RC0 version

Have a nice day and be good people.

x-posted from http://blogs.microsoft.co.il/blogs/tamir
Free Microsoft Expression series video training catalogs

MSDN download center just published video catalogs, where you can find sample chapters of Total Training’s video series for Microsoft Expression studio. Worth to download and see. Here the breakdown by products

Also, if you are “in” Office development, it makes sense to take a look in to Data Connectivity Components for Office 2007 System. It can be used by non-Microsoft Office applications to read data from Office system files.

Happy downloading!

x-posted from http://blogs.microsoft.co.il/blogs/tamir
For all those, who have problems with running WPF Performance Profiling tool – Microsoft cares

Three days ago, I announced the new release of WPF Performance Profiling Tool. A couple hours after this was announced, I got a number of comments from you, readers. It was about issues with running this tool. I checked the issue and forwarded it to development team from Microsoft. The problem was in bad parsing of comma and point characters in this tool, when using it on non-US locale. Dev team took care about it and hopefully they will provide a fix soon.

Thank you for reading my blog, reporting and your awareness of such issues. This is very important to me and I’m really appreciate your efforts to help us to develop WPF community.

I’ll update you as soon as the patch will be available.

Thank you and Shana Tova!

image

x-posted from http://blogs.microsoft.co.il/blogs/tamir
Nokia Mail for Exchange 2.7 is out

New version of outstanding Exchange synchronization tool for Nokia phones is out. There are no big changes, except heart beat implementation of ActiveSync and fixes to contacts mapping bug is there. The main feature of this version is, that it can now run on any S60 phone (including 3.0, 3.1 and 3.2 devices), not only on E and N series. Full list of changes can be found here.

The bad news is, that Nokia MFE 2.7 still does not support inbox folders synchronization. This is the main feature missing in this great software. However, according the update rate, it should arrive soon.

Download Nokia Mail for Exchange 2.7 >>

x-posted from http://blogs.microsoft.co.il/blogs/tamir
The new version of WPF Performance Profiling Tool is available for download

Finally, after a long time of silence, the new version of WPF Performance Profiling Tool is available for download for x32 and x64 OSs.  So, what’s new there?

Ton of UI improvements for Visual Profiler

image

New search function to quick find elements in visual tree

image

Hot path (critical path) of CPU usage aside with CPU usage for single element

image

Configuration of tint for overlay windows

image

Live preview, ability to split columns, slider of graph duration, expanders to have cleaner screen and much much more

Perforator also got new UI and has history now.

image

There is new tool, named String allocation profiler

image

This tool is very useful for viewing and managing strings inside your application (another step toward normal localization support for WPF? Probably)

There are also some improvements in Event tracing tool. Select process for example :)

image

And much much more. Great thank to Josef and his team for this great work

Download the new version of WPF Performance Profiling Tool >>

x-posted from http://blogs.microsoft.co.il/blogs/tamir
Visual Studio snippet designer

Chicks love CodePlex as well as Microsoft loves it too and today they release extremely useful tool, that was internal for more, then three years. It named: “Visual Studio Snippet Designer”.

image

As you can, probably, understand. This tools is used to create and manage VS time savers - snippet files (introduced in VS2005)

image

This is great tool, that will help you a lot to save your time during regular everyday development. Any other word is unnecessary. Download, install and use it!

x-posted from http://blogs.microsoft.co.il/blogs/tamir
A little bit about batteries

I tired to write about programming, code and similar nerd stuff. So today I’ll write about … batteries. How is it? :)

Today, batteries are in use all over our life. We have a battery in our mobile phone, computer, camera, mp3 player, even microwave, alarm and hand clock. So, the main problem with batteries, scientists all over the world work about is how to extend the working and life time. Let’s try to understand how to know whether the battery is good for us.

How to measure batteries

The number, can tell us whether the battery will work longer for us is charge (or actual). We measure charge in Ampere/hours (Ah). One ampere-hour is equals to 3600 coulombs (ampere-seconds) and represents an amount of charge, transferred by a steady current of one ampere for one hour. As higher this number is, your battery will work longer for the same consumer.

image

What does “steady current” means?

Steady current is the power in watts, associated with an amount of electricity, named voltage (V). So, constant voltage, associated with one Ah produces the power of the battery in Watts per hour (Wh). So, why we cannot measure batteries in Wh? The problem is, that the power vary during charge and discharge process. So, the exact energy is the integral over time of the instantaneous voltage time and the current. Calculation of those three parameters is simple:

W = V * A

Today’s battery contains large number of elements (cells) with different fillings. As higher the number of elements, this your battery will work longer. Total work time may vary because of different parameters: charging methods, temperature, the way we’re charging it, number of charge-discharge cycles, etc.

Types of batteries

There are various batteries, however the most famous are following:

Li-ION (lithium-ion): Number of charge-discharge cycles is between 500 and 700. The number of it depends on the depth of discharge. As more the battery discharged, this less number of cycles the battery will provide. It necessary to make a number of cycles for 14-16 hours until the battery will provide its nominal capacity. Each cycle the battery’s current will be increased until the nominal.

Pros: Good energy to weight ration – the battery rather small in compare to the current because of their high energy density.
No memory effect (no loss of maximum energy capacity on repeatedly recharge after partial discharge)
Slow loss of charge when not in use

Cons: Those batteries might explode under certain conditions.
Energy loss starts directly after first charge, thus don’t buy this battery if you need spare battery and will not use it directly after purchase.

NiCd (Nickel-Cadmium): Number or charge-discharge cycles is between 1000-1500. This number might increase if you’re using the battery properly. However, you need to “train” this battery to assure maximum performance.

Pros: Tolerate to deep discharge for long period.
High energy density
Low self-discharge rate – about 20%/month

Cons: Cadmium is toxic material
Memory effect – wrong usage pattern may cause to “false bottom” effect. The battery will stop charging, before the total capacity gathered.
Negative temperature coefficient – As the cell temperature rose, the internal resistance fell.

NiMH (Nickel-metal hydride): Number of charge-discharge cycles is under 1000 and depends on depth of discharging. Those batteries are very similar to NiCd, however those batteries can have two or three times the capacity of an equivalent size NiCd, but discharge rate is also higher.

Pros: Less toxic, price effective and have higher capacity then NiCd
Memory effect

Cons: High self discharge rate
High application discharge rate
Voltage drop near as it nears full discharge

Li-Pol (Lithium-polymer): Number of charge-discharge cycles is very low 100-150 and depends on depth of discharging. Newer Li-Pol batteries has higher cycle durability, however they are still expensive. This is successor of Li-ION batteries.

Pros: Energy density is over 20% higher, then that of Li-ION.
High charge rate, about 1-3 minutes for cell
Greater life cycle degradation rate in comparison to Li-ION
Very efficient current per size ration
Non explosive

Cons: High cost
Low charge-discharge rate

Bottom line

Today, most of batteries are Li-ION, in spite of the fact, that it has high life cycle degradation rate. This is about two years by now for general user.  Also, those batteries degrades, even when not in use inside devices. You cannot leave uncharged battery unattended, because of the fact, that recharge may become impossible if the current drops under certain level. Also, those batteries are sensitive to temperature changes. On very low or high temperature the current degrades.

Ni-Cad batteries provides the most optimal life cycle degradation rate, however it very sensitive to the way, you’re using it. The ideal pattern for such batteries is “full charge - full discharge – full charge”, else you’ll suffer from the “memory effect”, I spoke earlier.

Chargers

As you already understand, there is a wide range of battery types, so chargers are also different for those types of batteries. So, how to know if the charger we have is good for me and what to choose.

The best charger for your battery is the one, you got with the device. It tuned for the battery you have. But can we use 3rd party chargers? The answer is: yes, we can, however it’s very important to understand, that if you have Li-ION battery and slow charger, you might be unable to charge it, even if you’ll put it in forever.

Slow chargers works with current equals to about 1/10 of nominal battery current, thus it will take about 10-12 hours to full recharge cycle. Quick chargers uses 1/2-1 of nominal battery current, so recharge cycle can take between 1 to 3 hours.

In both cases, do not leave NiCd and NiMH batteries in charger for a long time after the end of charging process. Even after the end of charge, those batteries keep charging, thus the quality will degrade. The story is different for Li-ION and Li-Pol batteries, those types of batteries are indifferent for overcharging. They usually have controllers to stop charging process after full recharge.

Car chargers are not very healthy devices to charge batteries. Each time you’re turn your car on, it initiate new charge cycle, thus the quality of battery will degrade.

How to prolong battery life time?

Let’s assume, that most of devices have Li-ION battery. Once, you got a new device do not start using it with minimal capacity, also do not want to full discharge. Recharge it number of times until the capacity will be equal to almost equal to the nominal power.

Also, switch your device to turn into idle mode after reasonable amount of time. It’s better, if it possible to switch or hibernate the device, rather then turn it into idle. Turn off all unused modules (such as GPS, Wi-Fi, Blootooth for mobile phones). Large number of concurrently running processes are also degrade the power quickly, so you can use Vista Battery Saver to decrease this number in Windows Vista. In PDAs, almost all plugins for battery level and processes performance measurement usually only use the battery, rather then provide usable information. If you can, turn GPRS in your mobile phones and use only GSM, this might save about 30% of energy without QoS degradation. Also, in places without coverage mobile phones increase the level of signal, so decrease the time, you can use the device.

If during the charging process, the temperature of battery exceeds 60C (140F), stop charging immediately and recycle the charger. If the battery become swollen, recycle the battery. If Ni-MH battery discharges very quick, it’s possible to restore it, however restore is impossible for Li-ION batteries. If you’re feeling, that the capacity of Ni-MH battery degrades, you can calibrate it. Never train Li-ION batteries, the quality will degrade.

Do not store your battery empty. Charge it unto 40%-50% of nominal capacity and store in 15C (60F) in fridge.  Also it worth to recharge unused batteries once a half-year. However, the best you can do is to use battery. This what it designed for.

x-posted from http://blogs.microsoft.co.il/blogs/tamir
Next page »
Page view counter