Hm... recently I have googled into one veeeery usefull (for SEOs) post
I found that blog while I was searching for the ways to trackback my own posts from other blog-engines so that I could see the list of the links to my posts...
Friday, April 25, 2008
Thursday, April 24, 2008
XAML+LoadComponent VS pure code - where are my name scopes???
Recently my coworker faced one interesting problem. He was looking through the sample for the Josh's article on 3D in WPF, and said that he had noticed one strange thing - whenever you try to replace the loading of the Viewport3D from XAML with in-code creation, you get an exception in RegisterName methods, saying that there is no name scope for the provided element.
So, what is the difference between loading XAML and creating element from code? I made a short research using the greatest tool in a .NET world, Reflector, and it turned out that in case when XamlReader (or, to be more specific, BamlRecordReader) meets some element, that does not support INameScope interface, it creates the namescope itself, and attaches it to the element (NameScope.SetNameScope(dependencyObject, new NameScope());).
Finally, to resolve the issue with an exception, we have manually created the NameScope and attached it to the viewport.
Also, XamlReader calls BeginInit and EndInit methods whenewer the loaded element supports ISupportInitialize interface. So you should remember to use that too when you create visual element in code.
So, what is the difference between loading XAML and creating element from code? I made a short research using the greatest tool in a .NET world, Reflector, and it turned out that in case when XamlReader (or, to be more specific, BamlRecordReader) meets some element, that does not support INameScope interface, it creates the namescope itself, and attaches it to the element (NameScope.SetNameScope(dependencyObject, new NameScope());).
Finally, to resolve the issue with an exception, we have manually created the NameScope and attached it to the viewport.
Also, XamlReader calls BeginInit and EndInit methods whenewer the loaded element supports ISupportInitialize interface. So you should remember to use that too when you create visual element in code.
Thursday, April 10, 2008
WPF tips: Get your own logical parent
Have you ever wondered how does the Popup knows its inheritance context, its logical parent and the route for the routed events after you set PlacementTarget property? Or how does the ContextMenu knows where to fire the commands?
Today I have incidentally found the answer.
Whenever you have the FrameworkElement, that does not have any kind of parent set directly( neither visual, nor logical ), you can choose your parent yourself :)
To do so, you should override GetUIParentCore() method and return whatever logical parent you want – one-way link will be created, so you will know who is your parent, and your parent could unaware of your existence :)
BTW Popup returns its PlacementTarget property value in this method.
This mechanism could be used to implement custom inheritance context in some cases, so it is really important to remember of its existence.
Today I have incidentally found the answer.
Whenever you have the FrameworkElement, that does not have any kind of parent set directly( neither visual, nor logical ), you can choose your parent yourself :)
To do so, you should override GetUIParentCore() method and return whatever logical parent you want – one-way link will be created, so you will know who is your parent, and your parent could unaware of your existence :)
BTW Popup returns its PlacementTarget property value in this method.
This mechanism could be used to implement custom inheritance context in some cases, so it is really important to remember of its existence.
Saturday, April 5, 2008
Public Folder Watcher
Yesterday I have created one more blog - the one for the Public Folder Watcher (blog is here).
Public Folder Watcher is a small addon for Microsoft Outlook, written by me.
I decided to implement it as soon as we installed Microsoft Exchange Server on our server at ArtfulBits.
We needed to share some data among all of the developers(and so do now), so at the time, Public Folders were the most suitable for that. But there were no notifications about the new items in Public Folders, so such approach was useless and so I decided to implement this addon :)
Now I can not even imagine how our company would live without this small addon - it monitors both Public Folders and emails and displays the list of the unread emails and posts. Almost all of my coworkers (at least 40 of them) and all of the managers use Public Folder Watcher to be always aware of the new emails or posts.
I hope others will find this addon usefull too and regard me for my work with 15$ :) That means that the Public Folder Watcher can be downloaded here, it's trial key can be got here, and it can be bought here .
Public Folder Watcher is a small addon for Microsoft Outlook, written by me.
I decided to implement it as soon as we installed Microsoft Exchange Server on our server at ArtfulBits.
We needed to share some data among all of the developers(and so do now), so at the time, Public Folders were the most suitable for that. But there were no notifications about the new items in Public Folders, so such approach was useless and so I decided to implement this addon :)
Now I can not even imagine how our company would live without this small addon - it monitors both Public Folders and emails and displays the list of the unread emails and posts. Almost all of my coworkers (at least 40 of them) and all of the managers use Public Folder Watcher to be always aware of the new emails or posts.
I hope others will find this addon usefull too and regard me for my work with 15$ :) That means that the Public Folder Watcher can be downloaded here, it's trial key can be got here, and it can be bought here .
Friday, April 4, 2008
Weird solutions: Ho can I force WPF control to rerender itself.
Today I found out some strange solution for forcing control to invalidate itself.
It turned out that by default control invalidates itself only in case it's render size has been changed, his visual parent has been changed, or some of it's dependency properties with AffectsRender option set is changed. (also there are some other weird cases when control suddenly decides to rerender it's appearance)
So I decided that maybe I can use FrameworkElement's ability to react to the AffectsRender option - I implemented the attached dependency property, and tried setting it to some rendom values on an object I needed to invalidate...and it worked :)
Here is some sample class, that could be used to implement such workaround:
public class RenderingHelper : DependencyObject
{
private static int s_last = 0;
public static int GetForceRerender( DependencyObject obj )
{
return (int)obj.GetValue( ForceRerenderProperty );
}
public static void SetForceRerender( DependencyObject obj, int value )
{
obj.SetValue( ForceRerenderProperty, value );
}
public static readonly DependencyProperty ForceRerenderProperty = DependencyProperty.RegisterAttached( "ForceRerender", typeof( int ), typeof( RenderingHelper ),
new FrameworkPropertyMetadata( 0, FrameworkPropertyMetadataOptions.AffectsRender ) );
public static void InvalidateRender( Visual target )
{
SetForceRerender( target, s_last++ );
}
}
You should keep in mind that invalidation of a visual calls it's OnRender method and recreates only part of the elements visual graph. All Visual's children are left the same, so if you need to invalidate the appearance of the entire visual subtree, you should add FrameworkPropertyMetadataOptions.Inherits to the property options.
It turned out that by default control invalidates itself only in case it's render size has been changed, his visual parent has been changed, or some of it's dependency properties with AffectsRender option set is changed. (also there are some other weird cases when control suddenly decides to rerender it's appearance)
So I decided that maybe I can use FrameworkElement's ability to react to the AffectsRender option - I implemented the attached dependency property, and tried setting it to some rendom values on an object I needed to invalidate...and it worked :)
Here is some sample class, that could be used to implement such workaround:
public class RenderingHelper : DependencyObject
{
private static int s_last = 0;
public static int GetForceRerender( DependencyObject obj )
{
return (int)obj.GetValue( ForceRerenderProperty );
}
public static void SetForceRerender( DependencyObject obj, int value )
{
obj.SetValue( ForceRerenderProperty, value );
}
public static readonly DependencyProperty ForceRerenderProperty = DependencyProperty.RegisterAttached( "ForceRerender", typeof( int ), typeof( RenderingHelper ),
new FrameworkPropertyMetadata( 0, FrameworkPropertyMetadataOptions.AffectsRender ) );
public static void InvalidateRender( Visual target )
{
SetForceRerender( target, s_last++ );
}
}
You should keep in mind that invalidation of a visual calls it's OnRender method and recreates only part of the elements visual graph. All Visual's children are left the same, so if you need to invalidate the appearance of the entire visual subtree, you should add FrameworkPropertyMetadataOptions.Inherits to the property options.
Subscribe to:
Posts (Atom)