(Lviv community of .NET developers)

Recent posts

Data binding the SplitButton’s ContextMenu

October 2, 2007 07:31 by realnero

Someone recently posted an article to CodeProject which provides a pretty nice implementation of a “split button.” WPF does not have a built-in split button, so this is a solid addition to the standard control library. The original article can be found here.

The author of SplitButton allows you, the developer, to easily populate its ContextMenu by adding child MenuItem elements to the SplitButton in XAML. That looks something like so:

Bound SplitButton (manual)

... >>>

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories:
Actions: Permalink | Comments (0) | RSSRSS comment feed

Modifying the auto tooltip of a Slider

September 17, 2007 06:14 by realnero

This blog post answers a question on the WPF Forum which asks how to programmatically affect the text in a Slider’s auto tooltip.

Slider has a nice feature where it displays an “auto tooltip” as the user slides the thumb.  The tooltip displays the current value of the Slider, and it follows the thumb as the user slides it back and forth.  Slider exposes two properties that allow you to affect the auto tooltip, AutoToolTipPlacement and AutoToolTipPrecision.  The latter allows you to affect how accurate the tooltip’s text is, relative to the Slider’s value.  What is not possible, however, is to modify the text in the auto tooltip.  This blog post shows one workaround for that problem.

I tried to gain access to the auto tooltip in many ways, but none succeeded. As a last resort, I decided to use a little reflection to gain access to the _autoToolTip field in Slider.  After poking around in Reflector I realized that the auto tooltip’s content is only updated in two virtual methods: OnThumbDragStarted and OnThumbDragDelta.  Armed with that information it was trivial to create a Slider subclass which makes it possible to format the auto tooltip’s display text.

 

... >>>

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories:
Actions: Permalink | Comments (0) | RSSRSS comment feed

WPF Interactive Image Cropping Control

September 14, 2007 09:25 by realnero

Introduction

Recently a friend of mine who has just started a company pointed me at this site which does lots of fancy image editing. Although he doesn't know XAML or Sliverlight he reckoned some of the stuff they were doing was excellent, and asked me to look into doing something similar in WPF. While this article represents only a small portion of what that website can do (namely image cropping) I feel that it outlines some useful techniques and study notes for those of you that may end up trying to do image editing applications in WPF/Silverlight. Although I cannot categorically state that 100% of this article will work with Silverlight as it has really been written in WPF, I am waiting to play with the managed version of Silverlight v1.1. JavaScript leaves me cold (nasty stuff). So after I've had a play with that I should be able to write WPF articles that I know will work with Silverlight. Till then, I'm afraid if you want a Silverlight version, you'll just have to try a code port for yourself.

So what is this article exactly? Well like I said, my friend asked me to create a posh image cropper in WPF. So that's really what it is. It's an image cropping control that may be placed within any other XAML and used to crop images. The cropping of the image is achieved by firstly drawing a shape and then moving the shape around to the desired position before completing and accepting the cropped image.

That's it, in a nutshell. It's a simple image cropper basically written in WPF.

... >>>

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: WinFx
Actions: Permalink | Comments (0) | RSSRSS comment feed

A base class which implements INotifyPropertyChanged

September 6, 2007 09:35 by realnero

The longer I’ve worked with WPF, the more implementations I have seen of the INotifyPropertyChanged interface.  It’s everywhere.  I have seen dozens upon dozens of classes all implement the interface separately, even though most of those classes descend directly from Object.  This blog post examines the virtues of creating a base class which implements that interface, and deriving as many classes as possible from it.

Consolidating your implementation of INotifyPropertyChanged into a base class has several benefits.

  1. You do not have to implement the same interface many times, which reduces the possibility of boredom (and programming errors…).
  2. You can easily use cached instances of PropertyChangedEventArgs, to avoid fragmenting the managed heap with semantically identical instances.
  3. You can easily use some reflection magic to verify that the property which allegedly changed actually exists (this is useful for debugging purposes, and is automatically turned off in Release builds).
  4. You can override a method to execute logic which must run after a property is set. 
... >>>

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: WinFx
Actions: Permalink | Comments (1) | RSSRSS comment feed

Prevent a binding from updating too frequently

September 6, 2007 08:04 by realnero

During my WPF presentation for the NYC .NET Developer Group a few days ago, someone in the audience asked a question about the data binding system which piqued my interest.  He asked if it is possible to control how frequently a binding target is updated. 

Suppose that you have a data source where a property’s value changes very rapidly, perhaps several dozen times per second.  You would not want the UI to display all of those values because it would just look like a blur.  It would be better to govern how often the binding source’s new values are pushed to the binding target.  The question is, how can you do that in WPF?

  One solution is to create a value converter which governs the data flow between source and target.  The converter can keep a time stamp which it uses to determine when the new source values can be pushed to the target.  Every time the data is pushed, the time stamp is updated so that the next push will not occur until a pre-defined duration has elapsed.

I put together a demo app which shows how to do this.  In the demo, the rapidly changing data source is called RandomNumberEngine.  It has a public property named Current, which returns a random number.  That random number changes once every millisecond.  When the value changes, the PropertyChanged event is raised so that the binding system will attempt to push that new value into a TextBlock in the UI.  The TextBlock’s Text property is bound to the Current property on the RandomNumberEngine, and that binding is where we use the UpdateThresholdConverter to govern how often the data is pushed.

Here is the XAML for the demo app’s main Window contents:

Update Threshold Converter (usage)

... >>>

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories:
Actions: Permalink | Comments (1) | RSSRSS comment feed

Работа с потоками в C# Часть 1

September 5, 2007 13:21 by realnero

1. Начало работы

Обзор и ключевые понятия

C# поддерживает параллельное выполнение кода через многопоточность. Поток – это независимый путь исполнения, способный выполняться одновременно с другими потоками.

Программа на C# запускается как единственный поток, автоматически создаваемый CLR и операционной системой (“главный” поток), и становится многопоточной при помощи создания дополнительных потоков. Вот простой пример и его вывод:

ПРИМЕЧАНИЕ

Все примеры предполагают, что импортируются следующие пространства имен (если этот момент специально не оговаривается):

using System;

using System.Threading;

class ThreadTest 
{
  static void Main()
  {
    Thread t = new Thread(WriteY);
    t.Start();            // Выполнить WriteY в новом потоке
    while (true) 
      Console.Write("x"); // Все время печатать 'x'
  }
 
  static void WriteY() 
  {
    while (true) 
      Console.Write("y"); // Все время печатать 'y'
  }
}

Вывод:

xxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxyyy
yyyyyyyyyyyyyxxxxyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxx
xxxxxxxxxyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyx
xxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxyyyy
yyyyyyyyyyyyxxxxy...
... >>>

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories:
Actions: Permalink | Comments (1) | RSSRSS comment feed

Office 2007 Style WPF Window

September 5, 2007 10:50 by realnero

The next challenge that I am going to share my solution with you is the Office 2007 like window style. As you know, the Office 2007 applications are using the layered windows functionality to display rounded corners and a custom title bar. This is how the typical  window in the new Office looks like:

 

... >>>

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: WinFx
Actions: Permalink | Comments (0) | RSSRSS comment feed

“Smart Tag” type of popup in WPF

August 27, 2007 22:00 by realnero

The other day I was searching around for examples of Office 2007 like “Smart Tag” type of popup implemented in WPF, but I could not find any with source code available. As you know that the tooltip control in WPF/XAML does not allow any controls you put inside a tooltip to receive focus or mouse click events, you have to use the primitive Popup control instead to achieve such functionality. So I decided to build one myself. It turns out the process is quite simple. The only trick that I find out and still not know how to solve elegantly is wiring up the delayed popup solely in XAML. Currently my implementation utilizes a custom service class that wires up the mouse events between the popup and the target control. The XAML part of the control is very simple:


Inside your Popup definition, you can define your Smart Tag popup as you would in any other XAML elements. The following is an example of a toolbar enclosed inside thepopup:


In order to support positioning the popup control in arbitrary location close to (but not border-to-border) its target control, you need to wire the MouseMove and MouseLeave events of both the Popup control and the target control. And you need a delayed hide/show service to ensure that the popup won’t flash if you quickly move your mouse around. This is achieved through a delayed DispatchTimer in the DelayedPopupService code.


Let me know what you think of this.

 

The source code is uploaded.

WpfSmartTagSample.zip (70,19 kb)


Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: WinFx
Actions: Permalink | Comments (0) | RSSRSS comment feed

What's New in WPF in the .NET FX 3.5 Beta 2 release

August 18, 2007 22:00 by realnero

Visual Studio 2008 Beta 2 and the .NET Framework 3.5 Beta 2 are now available! You can download them here. Read more about this release on Somasegar's annoucement post.What's new in WPF? Here's a non-comprehensive list:

 

  • Application Model

o        WPF builds on the new add-in model in .NET Framework 3.5 Beta 2 to allow developers to create visual add-ins, where add-ins provide UIs that are displayed by the host application. You’ll find the add-in types in the System.AddIn namespace in System.AddIn.dll, System.AddIn.Contract.dll, and System.Windows.Presentation.dll. o        XBAPs can now run in FireFox.o        Cookies can be shared between XBAPs and Web applications from the same site of origin.o        Improved XAML intellisense experience for higher productivity.o        Data binding and journaling by URI work together.

 

  • Data Binding

o        A new debugging mechanism makes it easier to debug data bindings. (new attached property: System.Diagnostics.PresentationTraceSources.TraceLevel)o        The data validation model now supports the IDataErrorInfo interface. (new class: System.Windows.Controls.DataErrorValidationRule)o        Improvements have been made to BindingListCollectionView to provide better support for binding to a collection that is of type BindingList and for LINQ.o        The behavior of data bindings with a CollectionView over an IEnumerable has been improved to provide better performance and better support for binding to results that are produced by LINQ.

 

  • 3D
    • UIElement concepts such as input, focus, and eventing have been brought to 3D. (new classes: System.Windows.UIElement3D which is abstract, and ContainerUIElement3D and ModelUIElement3D in the System.Windows.Media.Media3D namespace)
    • Developers can now place interactive 2D content onto a 3D object. (new class: System.Windows.Media.Media3D.Viewport2DVisual3D)
  • Documents/Annotations
    • The annotations framework now exposes the capabilities for matching annotations with the corresponding annotated objects. (new interface IAnchorInfo and new class TextAnchor in the System.Windows.Annotations namespace)
  • Better IME support, RichTextBox extensibility (new property IsDocumentEnabled), performance improvements, and more!
We'll be sharing samples here for you to play with - stay tuned!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: WinFx
Actions: Permalink | Comments (0) | RSSRSS comment feed

Defining and Using Shared Resources in a Custom Control Library

August 12, 2007 22:00 by realnero

The question about how to define and use shared resources in a custom library has come up a couple times lately and after much discussion with the developer (thanks Varsha), here is the answer. When an application looks for a resource, it looks at three levels in the following order: 

  1. The element level—This is the level at which the system starts with the element that references the resource then searches resources of the logical parent and so forth until the root element is reached.
  2. The application level—Resources are defined by the Application object.
  3. The theme level-- The theme level dictionaries are stored in a subfolder called Themes.  The files in the Themes folder correspond to a theme.  For example, you might have Aero.NormalColor.xaml, Luna.NormalColor.xaml, Royale.NormalColor.xaml, etc.  You can also have a file called generic.xaml.  When the system looks for a resource at the themes level, it first looks for it in the theme-specific file and then looks for it in generic.xaml.

For more information about resources, see Resources in the WPF SDK.

 

As a control library developer, you don’t have access to the Application object, so you have to put your resources at the element level or at the theme level.   Defining resources at the element level You can define shared resources at the element level by creating a custom resource dictionary and merging it with your control’s resource dictionary.  When you use this method, you can call your resource file anything you want and it can be in the same folder as your controls. Resources at the element level can also use simple strings as keys. The following shared resource is defined in a file called Dictionary1.XAML (nothing new here). 

<LinearGradientBrush     x:Key="myBrush"      StartPoint="0,0" EndPoint="1,1">

  <GradientStop Color="Red" Offset="0.25" />

  <GradientStop Color="Blue" Offset="0.75" />

</LinearGradientBrush>


 Once you've defined your dictionary, you need to merge it with your control's ResourceDictionary.  You can do this using XAML or code. Merging the ResourceDictionary in XAMLTo merge the resource dictionary using XAML, include the following in the XAML file of your custom control (in this case, a UserControl):  

<
UserControl.Resources>

  <ResourceDictionary>

    <ResourceDictionary.MergedDictionaries>

      <ResourceDictionary Source="Dictionary1.xaml"/>

    </ResourceDictionary.MergedDictionaries>

  </ResourceDictionary>

</UserControl.Resources>


When you reference a ResourceDictionary in XAML, a ResourceDictionary object is created each time you reference it.  So if you have 10 custom controls in your library and merge the shared ResourceDictionaries for each control by using XAML, you create 10 identical ResourceDictionary objects.  You can avoid this by creating a static class that returns the ResourceDictionary and merging the resources in code.   
Merging the ResourceDictionary in CodeHere is a class that returns a shared ResourceDictionary.    

internal static class SharedDictionaryManager

{

  internal static ResourceDictionary SharedDictionary

  {

    get

    {

      if( _sharedDictionary == null )

      {

        System.Uri resourceLocater = new System.Uri( "/CustomControlLibrary2;component/Dictionary1.xaml", UriKind.Relative );

        _sharedDictionary = ( ResourceDictionary )Application.LoadComponent( resourceLocater );

      }

      return _sharedDictionary;

    }

  }

  private static ResourceDictionary _sharedDictionary;

}

 

Then in the constructor of each custom control, merge the shared resource with the resources of the custom control before you call InitilizeComponent.  Because the property is static, the ResourceDictionary gets created only once. 

this.Resources.MergedDictionaries.Add(SharedDictionaryManager.SharedDictionary);
 

Defining resources at the theme level When you define a resource at the theme level, you must create a ComponentResourceKey for the resource of the key.  This isn’t too difficult, but it’s not as simple as assigning a string as the key. 
 

<
LinearGradientBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:Painter},                                ResourceId=ButtonBrush}" StartPoint="0,0" EndPoint="1,1">

  <GradientStop Color="Blue" Offset="0" />

  <GradientStop Color="White" Offset=".8" />

</LinearGradientBrush>



The TypeInTargetAssembly property indicates a type that is in the same assembly as generic.xaml.  It doesn’t restrict the types within the library that can use the resource.  To use the resource in a control, simply reference it by a ComponentResourceKey:    

<
Button

  Margin="0,10,0,0" Click="FillBrush"

  Background="{StaticResource {ComponentResourceKey TypeInTargetAssembly={x:Type local:Painter}, ResourceId=ButtonBrush}}"

  >

  Paint ellipse

</Button>



Note:  Visual Studio automatically created Themes/generic.xaml when you create a new custom control but not when you create a user control.  To use Themes/generic.xaml in a library of user controls, manually create the folder, create a new resource dictionary in that folder, and name it generic.xaml. 

Accessing the shared resources 
Regardless of what method you choose to create a shared dictionary, you can use the shared resources in XAML or code, just as you would any other resource.  Remember that the difference in the two is the type of the x:Key: Resources defined at the them level must be referenced by a ComponentResourceKey, while resources at the element level can be referenced by a string.    

<!--
myBrush is a shared resource in dictionary1.xaml.-->

<Rectangle Width="200" Height="200" Stroke="Black" StrokeThickness="2" Fill="{StaticResource myBrush}"/>

 

<!--ButtonBrush is a resource in generic.xaml-->   

<Button  Margin="0,10,0,0" Click="FillBrush"

         Background="{StaticResource {ComponentResourceKeyTypeInTargetAssembly={x:Type local:Painter}, ResourceId=ButtonBrush}}">

      Paint ellipse

</Button>


To get and use resources in code, use the FindResources or TryFindResources method.  These methods are defined for FrameworkElement and FrameworkContentElement, so you can call them directly on your control.            

// MyEllipseBrush is a theme level resource so it has a ComponentResourceKey.           
ComponentResourceKey brushKey = new ComponentResourceKey(typeof(Painter), "MyEllipseBrush");           
ellipseBrush = (Brush)this.TryFindResource(brushKey);
 

Whether you define your resources at the theme level or merge them at the element level depends on your scenario.  Here’s a summary of the things to keep in mind: 1)
       If you create the resource dictionary at the theme level, you have to use ComponentResourceKeys as keys instead of strings.  2)       Implicit style application does not occur on the theme level.  Suppose you want all the labels on your controls to have a certain style.  If you define the style in at the element level, you do not have to give the style an explicit key, the labels will use the style automatically.  This is not the case for resources at the theme level.  You must define a key and reference the style every place you want to use it.3)       If you use XAML to merge resources at the element level, a ResourceDictionary is created each time you reference the shared dictionary to merge it.  To use a single instance of the shared dictionary, you have to write code. 

 

The attached project defines contains two control libraries.  One library creates a ResourceDictionary in the Themes/generic.xaml file. The other library creates a shared ResourceDictionary and merges the shared dictionary with two custom controls in code.  

 

Attachment(s): SharedResources.zip

 

Source : http://blogs.msdn.com/wpfsdk/archive/2007/06/08/defining-and-using-shared-resources-in-a-custom-control-library.aspx

 

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: WinFx
Actions: Permalink | Comments (1) | RSSRSS comment feed