DarioSantarelli.Blog(this);

Archive for the ‘WPF’ Category

Two new projects released!

Posted by dariosantarelli on March 22, 2013


I’ve just published two new projects I’ve worked on in the last months:

LogLive

LogLive is free software for Windows written in .NET (WPF 4) that enables you to perform real-time monitoring on different types of log sources through components called “listeners”.

TextTableFormatter.NET

TextTableFormatter is a .NET porting of Java TextTableFormatter.
This library renders tables made of characters. The user add cells and can add format characteristics like predefined/custom table styles, text alignment, abbreviation, column width, border types, colspan, etc.

In the next months I will publish other projects, so please stay tuned! 🙂

Advertisements

Posted in .NET Framework, About Me..., Microsoft Technology, Programming, WPF | Leave a Comment »

[WPF] From Visual to Bitmap

Posted by dariosantarelli on October 21, 2012


I’d like to share a couple of extension methods that helped me in situations where I needed to convert some rendered WPF windows or controls to bitmaps. Many devs know how complex this task was in Windows Forms. Instead, in WPF it’s quite simple, at least if you’re familiar with the RenderTargetBitmap class, and the range of BitmapEncoders. In order to convert a visual to a bitmap, I like to see something like this:

myVisual.ToBitmapSource().ToPngFile(@”C:\ScreenShot.png”);

The ToBitmapSource() extension method allows you to get a single, constant set of pixels at a certain size and resolution representing the visual (please note that a BitmapSource uses automatic codec discovery, based on the installed codecs on the user’s system). I’ve always found useful to replace the default black background that WPF reserves for transparency with a custom brush. So I introduced the transparentBackground parameter (default: white) which overrides the default black one.

public static BitmapSource ToBitmapSource(this Visual visual, Brush transparentBackground)
{
  var bounds = VisualTreeHelper.GetDescendantBounds(visual);
  var bitmapSource = new RenderTargetBitmap((Int32)bounds.Width, (Int32)bounds.Height, 96, 96, PixelFormats.Pbgra32);
  var drawingVisual = new DrawingVisual(); 
  using (var drawingContext = drawingVisual.RenderOpen())
  {
    var visualBrush = new VisualBrush(visual);
    drawingContext.DrawRectangle(transparentBackground, null, new Rect(new Point(), bounds.Size));
    drawingContext.DrawRectangle(visualBrush, null, new Rect(new Point(), bounds.Size));
  }

  bitmapSource.Render(drawingVisual);
  return bitmapSource;
}

public static BitmapSource ToBitmapSource(this Visual visual)
{
  return visual.ToBitmapSource(Brushes.White);
}

public static void ToPngFile(this BitmapSource bitmapSource, string fileName)
{
  var encoder = new PngBitmapEncoder();
  encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
  using (var file = File.Create(fileName)) encoder.Save(file);
}

Posted in .NET Framework, C#, Microsoft Technology, WPF | Tagged: , | 1 Comment »

[WPF] Registering the “pack://” scheme in unit tests

Posted by dariosantarelli on August 26, 2011


A while ago I tried to test some WPF resources stored in an assembly (BAML). When I tried to execute the following code in a unit test…

[TestMethod]

public void MyStyle_Should_Be_Loaded()

{           

  ResourceDictionary dictionary = new ResourceDictionary();

  dictionary.Source = new Uri(“pack://application:,,,/TestClassLibrary;component/ResourceDictionary.xaml”,

                              UriKind.RelativeOrAbsolute);

  object style = dictionary[“myStyle”];

 

  Assert.IsNotNull(style);

  Assert.IsTrue(style is Style);

}

… I received the following strange error while trying to instantiate the Uri class…

System.UriFormatException: Invalid URI: Invalid port specified.

But why?
The answer is not so obviuos. That’s because I was executing that code while the pack:// scheme wasn’t yet registered. In fact, this scheme is registered when the Application object is created. The very simple solution is to execute the following code just before executing the test…

[TestInitialize
public void OnTestInitialize() 
{   
   if (!UriParser.IsKnownScheme("pack")) new System.Windows.Application();
} 
 

HTH

Posted in .NET Framework, WPF | 2 Comments »

[WPF] Inheritance and DataTemplates

Posted by dariosantarelli on July 28, 2011


In this post I will show how different DataTemplates related to a hierarchy of classes can be nested and, therefore, reused. The concept is very simple, but its applications in a real scenario could be not so trivial!

Let’s assume to have a base ViewModel useful for editing and saving an object of your model. If the object class is subject to some derivations, maybe you’d like to derive your base ViewModel too in order to fulfill the model inheritance hierarchy. Moreover, most probably you have to define different editing views taking into account the whole inheritance hierarchy. In that case, maybe you’d like to reuse more XAML as possible.

So, let’s assume to have a base abstract Customer class and some concrete specializations, like EducationCustomer and GovernmentCustomer (see image below).   Customer class hierarchyThen, we design ViewModels in order to edit concrete instances of Customer class. In the class diagram below you can see a base ItemEditViewModel<T> which consists in a simple generic ViewModel which exposes a generic Item to be modified and a SaveCommand to persist it somewhere. The class also defines an abstract method OnCanSaveItem() which a concrete implementation must override in order to specify its own validation rules.   ViewModel hierarchy

public abstract class CustomerEditViewModel<T> : ItemEditViewModel<T> where T : Customer
{
 public CustomerEditViewModel(T customer) : base(customer) { }
 public CustomerEditViewModel() { } 

 protected override bool OnCanSaveItem() 
 {
 if (Item == null)  return false; 
 return (!string.IsNullOrWhiteSpace(Item.Name) && !string.IsNullOrWhiteSpace(Item.Email)); 
 } 
}

public class EducationCustomerEditViewModel : CustomerEditViewModel<EducationCustomer> 
{
 public EducationCustomerEditViewModel() : base() { }
 public EducationCustomerEditViewModel(EducationCustomer customer) : base(customer) { } 

 protected override bool OnCanSaveItem() 
 {
 if (!base.OnCanSaveItem()) return false;
 else return (!string.IsNullOrWhiteSpace(Item.SchoolName)); 
 } 
}  

public class GovernmentCustomerEditViewModel : CustomerEditViewModel<GovernmentCustomer>
{
  public GovernmentCustomerEditViewModel() : base() { }
  public GovernmentCustomerEditViewModel(GovernmentCustomer customer) : base(customer) { }

  protected override bool OnCanSaveItem()
  {
   if (!base.OnCanSaveItem()) return false;
   else return (!string.IsNullOrWhiteSpace(Item.AgencyName));
  }
}

Ok, we have just defined model and viewmodels. Now the interesting part! Our datatemplates could share some portions of XAML (e.g. the edit DataTemplate of the GovernmentCustomer is quite identical to the DataTemplate of the EducationCustomer, but it differs from the former just for a field). So, how can we reuse DataTemplates? First, we can define the edit DataTemplate for the base Customer class…

<DataTemplate x:Key="customerEditTemplate" DataType="{x:Type m:Customer}">
  <Grid>
    ...
    <TextBlock Text="Name" ... />
    <TextBox Text="{Binding Path=Name, Mode=TwoWay}" ... Background="AliceBlue" />
    <TextBlock Text="Email" ... />
    <TextBox Text="{Binding Path=Email, Mode=TwoWay}" ... Background="AliceBlue" />
  </Grid>
</DataTemplate>

 
and then, we can reuse the XAML above in the edit DataTemplate for the GovernmentCustomer and the EducationCustomer.

<DataTemplate x:Key="governmentCustomerEditTemplate" DataType="{x:Type m:GovernmentCustomer}">
  <StackPanel>
    <ContentPresenter ContentTemplate="{StaticResource customerEditTemplate}" />
    <Grid>
    ...
     <TextBlock Text="Agency" ... />
     <TextBox Text="{Binding Path=AgencyName, Mode=TwoWay}" ... Background="LightPink" />
   </Grid>
  </StackPanel>
</DataTemplate>

<DataTemplate x:Key="educationCustomerEditTemplate" DataType="{x:Type m:EducationCustomer}">
  <StackPanel>
    <ContentPresenter ContentTemplate="{StaticResource customerEditTemplate}" />
    <Grid>
      ...
      <TextBlock Text="School" ... />
      <TextBox Text="{Binding Path=SchoolName, Mode=TwoWay}" ... Background="Yellow" />
    </Grid>
  </StackPanel>
</DataTemplate>

 
OK, that’s all. Finally, a simple view can be implemented as below…

<Window ...>
  <Window.Resources>
    <m:GovernmentCustomer x:Key="governmentCustomer" />
    <m:EducationCustomer x:Key="educationCustomer" />
    <vm:GovernmentCustomerEditViewModel x:Key="governmentCustomerEditVM" Item="{StaticResource governmentCustomer}" />
    <vm:EducationCustomerEditViewModel x:Key="educationCustomerEditVM" Item="{StaticResource educationCustomer}" />
  </Window.Resources>

 

  <StackPanel DataContext="{StaticResource governmentCustomerEditVM}" Margin="10">
    <ContentPresenter Content="{Binding Path=Item}" ContentTemplate="{StaticResource governmentCustomerEditTemplate}" />
    <Button Content="Save"Command="{Binding Path=SaveItemCommand}"... />
  </StackPanel>
</Window>

 
As you can see, in this example the edit DataTemplate is referenced by key, but in a real scenario you can define your own mechanism to bind the right ViewModel to a DataTemplate for the Item to be edited and saved. In this example, the output result is the following

EducationCustomer edit WindowGovernmentCustomer edit Window

HTH

Posted in WPF | 1 Comment »

[WPF] Binding multiple command parameters using MultiBinding

Posted by dariosantarelli on November 7, 2010


In this post, I’d like to show how we can pass multiple values into an ICommand implementation by using the CommandParameter property of an input control. This is useful especially in MVVM architectures, so that the View can interact with the ViewModel in a clean way, facing the fact that the Execute method of the ICommand interface allows only a single object.
A solution is to use the MultiBinding class which allows us to define a collection of Binding objects attached to the target CommandParameter property of our input control. In a concrete example, let’s consider a simple search box with an OK button and a checkbox “ignore case”. The OK button is bound to a custom FindCommand defined in the ViewModel.
When the user clicks on the OK button, we want two parameters to be passed to the command: the string to be searched and the “ignorecase” option. How can we bind these two parameters to the Button’s CommandParameter?
Well, first we have to create a class to hold the parameters.

public class FindCommandParameters
{
  public string Text { get; set; }
  public bool IgnoreCase { get; set; }
}

After that, we have to create a class that implements the IMultiValueConverter interface. This simply converts our multiple parameters into the class that we have defined before.

public class FindCommandParametersConverter : IMultiValueConverter
{ 
  public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    FindCommandParameters parameters = new FindCommandParameters(); 
    foreach (var obj in values)
    { 
       if (obj is string) parameters.Text = (string)obj;                
       else if (obj is bool) parameters.IgnoreCase = (bool)obj;
    } 
    return parameters;
  }
  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}

As you can see in the code above, we can iterate through the list of input values of the Convert method, checking their type, and then correctly assign the properties of the parameter class. Obviously you can implement different solutions (you always know the order of the parameters set in the XAML), but the most important thing at this point is that the return value of the Convert method is what will be passed as argument to the Execute method of our FindCommand.
To wire up the XAML to take advantage of this class, we have to include the <Button.CommandParameter> element.  This contains the <MultiBinding> element, which has the “Converter” attribute. In the code below, the converter type is added as a resource to the button to make this post easier to read, but convention usually dictates resources are added at the Window level to allow reuse and readability.
Under the MultiBinding.Bindings element, we add a <Binding> element for each parameter that we need to pass into the command.

<TextBox x:Name="txtFind" />
<CheckBox x:Name="chkFindIgnoreCase" Content="Ignore case" />
 <Button Command="{Binding FindCommand}" Content="OK">
  <Button.Resources>
    <ui:FindCommandParametersConverter x:Key="findCommandParametersConverter" />
  </Button.Resources>
  <Button.CommandParameter>
    <MultiBinding Converter="{StaticResource findCommandParametersConverter}">
      <MultiBinding.Bindings>
        <Binding ElementName="txtFind" Path="Text" />
        <Binding ElementName="chkFindIgnoreCase" Path="IsChecked" />
      </MultiBinding.Bindings>
    </MultiBinding>
  </Button.CommandParameter>
</Button>

The final step is to consume the FindCommandParameters object instance in our FindCommand’s CanExecute and Execute methods.

Posted in WPF | Tagged: , , | 1 Comment »

FluidKit for WPF

Posted by dariosantarelli on March 17, 2008


On CodePlex you can find FluidKit, a WPF library containing a powerhouse of controls, frameworks, helpers, tools, etc. for productive WPF development. Here is the introductory blog post.
Available controls:

  • ImageButton
  • DragDropManager
  • GlassWindow
  • BalloonDecorator
  • ItemSkimmingPanel + SkimmingContextAdorner
  • PennerDoubleAnimation
  • ElementFlow ( Very  powerful ): allows you to display your items in different carousel like modes

Posted in .NET Framework, Microsoft Technology, WPF | Leave a Comment »

WPF Tools and Controls

Posted by dariosantarelli on July 15, 2007


I’d like to link Mike Swanson’s blog to pay attention to an interesting list of tools and controls you can use to build applications for the WPF.

Posted in .NET Framework, Microsoft Technology, WPF | Leave a Comment »

WPF: using IValueConverter

Posted by dariosantarelli on July 15, 2007


IValueConverter is a very useful interface (defined into the System.Windows.Data namespace in presentationframework.dll) that allows binding between different property types in WPF. Here is an example: we need a simple and reusable way to bind our custom properties (orders properties precisely) to a Listbox presentation properties. Well, by implementing the IValueConverter interface, for each ListBoxItem we can convert the value of the Priority property of our business object Order in the value of the Foreground property of the corresponding TextBlock which shows the Order name.
So, let’s define our Order class:

public class Order { private string _Name; private Priority _Priority; public Order() {} public Order(string name, Priority priority) { _Name = name; _Priority = priority; } public string Name { get { return _Name; } set { _Name = value; } } public Priority Priority { get { return _Priority; } set { _Priority = value; } } } public enum Priority : short { High=2,Normal=1,Low=0 } }

Now, by using XAML markup code we define a PriorityConverter class as a Converter inside the binding towards the Foreground property of the TextBlock containing the order name, while in the codebehind we define the PriorityConverter class as IValueConverter interface implementation:

<Window ... xmlns:mydata="clr-namespace:MyNamespace"> <Window.Resources> <DataTemplate DataType="{x:Type mydata:Order}"> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding Path=Name}"> <TextBlock.Foreground> <Binding Path="Priority"> <Binding.Converter> <mydata:PriorityConverter /> </Binding.Converter> </Binding> </TextBlock.Foreground> </TextBlock> </StackPanel> </DataTemplate> </Window.Resources> <StackPanel> <TextBlock>Orders List.</TextBlock> <ListBox Name="ordersListBox" ItemsSource="{Binding}"></ListBox> </StackPanel> </Window>

public class PriorityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value != null) { Priority priority = (Priority)value; BrushConverter colorConverter = new BrushConverter(); switch (priority) { case Priority.High: return colorConverter.ConvertFromString("#FF0000") as Brush; case Priority.Normal: return colorConverter.ConvertFromString("#000000") as Brush; case Priority.Low: return colorConverter.ConvertFromString("#0000FF") as Brush; default: break; } } return null; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return null; } }

In this case, the ConvertBack method implementation isn’t necessary, because the needed binding is one-way, from business logic layer to presentation layer. Moreover, the BrushConverter object can return an object representing a Brush by invoking the ConvertFromString method on a hexadecimal string representation of a color.
An advantage of this approach is the reusability, because above all it allows very simple implementations in those contexts in which the presentation layer can be completely changed, mantaining the business logic layer unchanged.

Posted in .NET Framework, WPF | Leave a Comment »