Friday, November 11, 2011

Reformatting All .xaml Files in Visual Studio Solution

 

Today I decided to format all .xaml documents in a solution so that all attributes are placed on a separate line and also to line nested tags on correct positions.

Actually I already setup settings in Visual Studio Tools menu a long time ago, but some developers working on the same project forget to format documents before check in – the result is - to comfortably read the file in standard format I need to check out the file and re-format it.

I decided to format all files in a solution so at least some time I don’t need to do this Smile

I have found very good answer on Stack Overflow:

auto format all files in solution in visual studio 2010

This works fine in Visual Studio 2008 too.

I had to modify a script a little to allow iterating over solution folders as well.

My mods allowed only 1 hierarchy level of solution folders to be supported – but this can be extended by recursive function call in first method resolving projects.

 

Here is the script:

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics

Public Module Module1

    Sub IterateFiles()
        Dim solution As Solution = DTE.Solution

        For Each prj As Project In solution.Projects

            If (prj.ConfigurationManager IsNot Nothing) Then
                ' It's a project!
                If (prj.UniqueName = prj.Name) Then IterateProjectFiles(prj.ProjectItems)
            Else
                If (prj.ProjectItems IsNot Nothing) Then
                    For Each projectItem In prj.ProjectItems
                        If (projectItem.SubProject IsNot Nothing) Then
                            IterateProjectFiles(projectItem.SubProject.ProjectItems)
                        End If
                    Next
                End If
            End If
        Next
    End Sub

    Private Sub IterateProjectFiles(ByVal prjItms As ProjectItems)
        For Each file As ProjectItem In prjItms
            If file.SubProject IsNot Nothing Then
                FormatFile(file)
                If file.ProjectItems IsNot Nothing Then
                    IterateProjectFiles(file.ProjectItems)
                End If

            ElseIf file.ProjectItems IsNot Nothing AndAlso file.ProjectItems.Count > 0 Then
                FormatFile(file)
                If file.ProjectItems IsNot Nothing Then
                    IterateProjectFiles(file.ProjectItems)
                End If
            Else
                FormatFile(file)
            End If
        Next
    End Sub

    Private Sub FormatFile(ByVal file As ProjectItem)
        'Exit Sub
        DTE.ExecuteCommand("View.SolutionExplorer")
        If file.Name.EndsWith(".xaml") Then
            file.Open()
            file.Document.Activate()

            DTE.ExecuteCommand("Edit.FormatDocument", "")

            file.Document.Save()
            file.Document.Close()
        End If
    End Sub

End Module

Happy Coding

Kirill

Monday, May 23, 2011

VisibleBinding – Markup Extension Allowing to Only Enable Binding When Target Is Visible

I tried to solve a number of performance problems while tuning WPF application I work on currently.

One of things I wanted to do is – make bindings effective only when control that uses them becomes visible, and don’t update binding target when target is invisible.

I end up creating the markup extension allowing me to do so.

Just use markup extension in format “{namespace:VisibleBinding SomeProperty"}” instead of standard “{Binding SomeProperty}” to achieve this.

note:

1) Binding target will be updated as normally when target is visible.

2) Binding target will not be updated when target is invisible.

3) once target becomes visible the binding becomes effective and therefore at this moment target will be updated with effective value from binding right away.

 

Here is the code:

public class VisibleBinding : BindingDecoratorBase
    {
        #region Class level variables

        private FrameworkElement mTargetObject;
        private DependencyProperty mTargetProperty;
        private PropertyChangeNotifier mNotifier;

        #endregion

        #region Constructor

        public VisibleBinding()
            : base()
        {
            Mode = BindingMode.OneWay;
        }

        public VisibleBinding(string path)
            : base(path)
        {
            Mode = BindingMode.OneWay;
        }

        private VisibleBinding(Binding binding, FrameworkElement targetObject, DependencyProperty targetProperty)
            : base(binding)
        {
            Mode = BindingMode.OneWay;

            Init(targetObject, targetProperty);
        }

        #endregion

        #region Methods

        public static void SetVisibleBinding(Binding binding, FrameworkElement targetObject, DependencyProperty targetProperty)
        {
            new VisibleBinding(binding, targetObject, targetProperty);
        }

        private void AttachTargetObject()
        {
            SetVisibleBinding(mTargetObject, this);
        }

        private void DetachTargetObject()
        {
            SetVisibleBinding(mTargetObject, null);
        }

        private void AttachTargetProperty()
        {

        }

        private void DetachTargetProperty()
        {

        }

        private void AttachExpression()
        {

        }

        private void DetachExpression()
        {

        }

        private void mNotifier_ValueChanged(object sender, EventArgs e)
        {
            CheckBindings();
        }

        private void CheckBindings()
        {
            if (mNotifier != null && mNotifier.Value is bool)
            {
                if ((bool)mNotifier.Value)
                {
                    SetBinding();
                }
                else
                {
                    ClearBinding();
                }
            }
        }

        private void ClearBinding()
        {
            if (mTargetObject != null && mTargetProperty != null)
            {
                mTargetObject.SetValue(mTargetProperty, mTargetObject.GetValue(mTargetProperty));
            }
        }

        private void SetBinding()
        {
            if (mTargetObject != null && mTargetProperty != null)
            {
                mTargetObject.SetBinding(mTargetProperty, mBinding);
            }
        }

        private void Init(DependencyObject targetObject, DependencyProperty targetProperty)
        {
            if (targetObject is FrameworkElement)
            {
                var element = targetObject as FrameworkElement;
                if (mTargetObject == null)
                {
                    if (mTargetObject != null)
                    {
                        DetachTargetObject();
                    }
                    mTargetObject = element;
                    if (mTargetObject != null)
                    {
                        AttachTargetObject();
                    }
                    if (mTargetProperty != null)
                    {
                        DetachTargetProperty();
                    }
                    mTargetProperty = targetProperty;
                    if (mTargetProperty != null)
                    {
                        AttachTargetProperty();
                    }
                    if (mNotifier != null)
                    {
                        mNotifier.ValueChanged -= mNotifier_ValueChanged;
                    }
                    mNotifier = new PropertyChangeNotifier(element, "IsVisible");
                    mNotifier.ValueChanged += mNotifier_ValueChanged;
                    CheckBindings();
                }
            }
        }

        #endregion

        #region Overrides

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            //delegate binding creation etc. to the base class
            var expression = base.ProvideValue(serviceProvider);

            DependencyObject targetObject = null;
            DependencyProperty targetProperty = null;
           
            if (serviceProvider != null)
            {
                TryGetTargetItems(serviceProvider, out targetObject, out targetProperty);
            }
            Init(targetObject, targetProperty);
            return expression;
        }

        #endregion

        #region DependencyProperties

        #region VisibleBinding

        /// <summary>
        /// Gets the value of the VisibleBinding attached property for a specified UIElement.
        /// </summary>
        /// <param name="element">The UIElement from which the property value is read.</param>
        /// <returns>The VisibleBinding property value for the UIElement.</returns>
        public static VisibleBinding GetVisibleBinding(UIElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }
            return (VisibleBinding)element.GetValue(VisibleBindingProperty);
        }

        /// <summary>
        /// Sets the value of the VisibleBinding attached property to a specified UIElement.
        /// </summary>
        /// <param name="element">The UIElement to which the attached property is written.</param>
        /// <param name="value">The needed VisibleBinding value.</param>
        public static void SetVisibleBinding(UIElement element, VisibleBinding value)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }
            element.SetValue(VisibleBindingProperty, value);
        }

        /// <summary>
        /// Identifies the VisibleBinding dependency property.
        /// </summary>
        public static readonly DependencyProperty VisibleBindingProperty =
            DependencyProperty.RegisterAttached(
                "VisibleBinding",
                typeof(VisibleBinding),
                typeof(VisibleBinding),
                new PropertyMetadata(null, OnVisibleBindingPropertyChanged));

        /// <summary>
        /// VisibleBindingProperty property changed handler.
        /// </summary>
        /// <param name="d">VisibleBinding that changed its VisibleBinding.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnVisibleBindingPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var control = sender as FrameworkElement;
            if (control != null)
            {
            }
        }

        #endregion

        #endregion
    }

To achieve the goal I used BindingDecoratorBase class. Thanks to Philipp Sumi for his work!

To make my class work – just download BindingDecoratorBase from his blog and include it into your project.

 

Another helper class which does nothing but listens to INotifyPropertyChanged PropertyChanged event is below:

public sealed class PropertyChangeNotifier : DependencyObject, IDisposable
    {
        #region Class level variables

        private WeakReference mPropertySource;

        #endregion

        #region Constructors

        public PropertyChangeNotifier(DependencyObject propertySource, string path)
            : this(propertySource, new PropertyPath(path))
        {
        }

        public PropertyChangeNotifier(DependencyObject propertySource, DependencyProperty property)
            : this(propertySource, new PropertyPath(property))
        {
        }

        public PropertyChangeNotifier(DependencyObject propertySource, PropertyPath property)
        {
            if (null == propertySource)
                throw new ArgumentNullException("propertySource");
            if (null == property)
                throw new ArgumentNullException("property");
            this.mPropertySource = new WeakReference(propertySource);
            Binding binding = new Binding();
            binding.Path = property;
            binding.Mode = BindingMode.OneWay;
            binding.Source = propertySource;
            BindingOperations.SetBinding(this, ValueProperty, binding);
        }

        #endregion

        #region PropertySource

        public DependencyObject PropertySource
        {
            get
            {
                try
                {
                    return this.mPropertySource.IsAlive
                    ? this.mPropertySource.Target as DependencyObject
                    : null;
                }
                catch
                {
                    return null;
                }
            }
        }

        #endregion

        #region Value

        /// <summary>
        /// Identifies the <see cref="Value"/> dependency property
        /// </summary>
        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value",
            typeof(object), typeof(PropertyChangeNotifier), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnPropertyChanged)));

        private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PropertyChangeNotifier notifier = (PropertyChangeNotifier)d;
            if (null != notifier.ValueChanged)
                notifier.ValueChanged(notifier, EventArgs.Empty);
        }

        /// <summary>
        /// Returns/sets the value of the property
        /// </summary>
        /// <seealso cref="ValueProperty"/>
        [Description("Returns/sets the value of the property")]
        [Category("Behavior")]
        [Bindable(true)]
        public object Value
        {
            get
            {
                return (object)this.GetValue(PropertyChangeNotifier.ValueProperty);
            }
            set
            {
                this.SetValue(PropertyChangeNotifier.ValueProperty, value);
            }
        }

        #endregion

        #region Events

        public event EventHandler ValueChanged;

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            BindingOperations.ClearBinding(this, ValueProperty);
        }

        #endregion
    }

Happy coding!

Kirill

Friday, April 1, 2011

I have a new computer :)

Finally I decided to buy new computer

My old one is not enough to do my daily work anymore.

The old one was

  • AMD Athlon-64 5400 Dual Core CPU
  • 2 Gb DDR 2 RAM memory
  • 250 Gb HDD

Well it worked, but it became slow with years – VS versions and heavy apps load this CPU and memory with ease.

Especially it is hard to do Silverlight and WPF development on such CPU.

This month I have bought new parts from amazon and yesterday finally the parts were delivered to me.

The new configuration looks like:

  • ASUS P8P67 PRO LGA 1155 SATA 6Gbps and USB 3.0 Supported Intel P67 DDR3 2400 ATX Motherboard
  • Intel Core i7-2600K Processor with 8 MB Cache, 3.40 GHz for Socket LGA1155 - Unlocked Boxed
  • ADATA Sandforce 2.5-Inch SATA II 3.0Gb/s Internal Solid State Drive 128 GB
  • ROLIMATECH ARMAGEDDON CPU COOLER SOCKET 1156 / 1366
  • G.SKILL 8GB (2 x 4GB) Ripjaws X Series DDR3 1600MHz 240-Pin PC3-12800 Desktop Memory F3-12800CL9D-8GBXL
  • Samsung SpinPoint F3 Desktop Class (4 X 1TB) Internal hard drive
  • Cooler Master 690 II Advanced Case
  • 650 W power supply unit from Spire
  • EVGA GTX 260 Core 216 Video Card

I think the configuration should take care of performance problems when working with multi-project solutions in Visual Studio 2010,

I decided to share this configuration to possible inspire reader of this post to do the same thing Smile

Yesterday I was assembling the parts unlit late night,

Here are some of the photos

image

image

image

image

image

image

 

The main points that should make the computer fast are

- of course the fast CPU, i7 2600K is in top 3 list of current production home processors. They are very good for single threaded apps and also for multi-threaded apps.

imageimage

- The AData 128 GB SSD has high read/write rate and very low seek times, which will speed up the system and applications dramatically

- The four 1 Tb HDDs will be built into two RAID 1 Mirrors making information stored on them two times safer

imageimage

- 8 Gb RAM should be enough for most software development tasks

I also ordered RevoDrive 120 Gb PCIe 4x SSD which claims to have Max Read: up to 540 MB/s, Max Write: up to 490 MB/s, Sustained Write: up to 470 MB/s, 4KB Random Write (Aligned): 65,000 IOPS

But I am still not sure whether I will be able to make this device a boot device as having so good technical characteristics this hardware is known to have some compatibility issues with different MBs.

I will update the post if have some more news on this to share Smile

Update:

My RevoDrive fit to my Asus P8P67 Pro Motherboard perfectly. I set it up as a boot disk (C:) and installed system on it.

image

Here are some more specs of a device:

Introducing the RevoDrive, a high performance PCIe Solid State Drive for consumer applications in desktops and workstation PCs

Focusing on both performance and affordability for consumers, the RevoDrive PCI-Express SSD is designed to accommodate a wide range of computing environments beyond everyday use to video-editing and other multi-media creation and management applications.
Moving beyond the bottleneck of SATA II, the RevoDrive features a PCI-E interface to deliver superior speeds up to 540MB/s reads and random 4k writes up to 75,000 IOPS. Designed for high-performance gaming PCs and workstations, the RevoDrive has the unique capability to run both Windows and your essential applications and games to not only provides a more responsive PC experience, but promote a cooler, quieter, and more energy efficient conditions compared to traditional mechanical hard drives.

The performance of my PC is really very good,

image

 

Cheers,

Kirill

Wednesday, February 9, 2011

Silverlight Spy – Free Edition

When I work on WPF projects I like very much the Snoop application. It allows me to debug visual tree of WPF app and look into what properties of controls are having what values in real time – to see what can be done to improve layout (like fixing margins etc.), what data bindings and data contexts are currently used and many other things. If you did not try Snoop – just try it – it is free and very useful.

When working in Silverlight I always wanted we have this kind of tool for Silverlight too – and I found it!

Silverlight Spy – is what I was looking for. The best thing about this app – is – it has Free Edition available. The licensing page on developer’s website says free edition is limited – but after evaluating free version few minutes I am pretty satisfied with what it provides.

I advice you to try it and I am sure you will find it useful!