Szukaj na tym blogu

wtorek, 13 września 2011

Przyszłość Silverlight i Microsoft BUILD

Przez ostatnie kilka tygodni (miesięcy), społeczność wrzała z powodu pogłosek na temat mizernej przyszłości technologii Silverlight.

Przyznam szczerze, że sam się lekko przestraszyłem ponieważ Silverlight okazał się dla mnie tym czymś w czym czuję się naprawdę dobrze, a perspektywa nie trafionej inwestycji w tą technologię była dla mnie co najmniej deprymująca.

Z lekkim przerażeniem czekałem na konferencję Microsoft BUILD na której miało okazać się czy firma z Redmond idzie w kierunku HTML5, CSS3 zapominając o starszych technologiach, czy też w całym ekosystemie Windows 8 znajdzie się miejsce dla Silverlight lub też bardziej ogólnie - technologii XAML-o podobnych.

Pierwszy dzień konferencji Microsoft BUILD na szczęście rozwiał moją niepewność dzięki czemu nadal będę mógł zgłębiać kolejne obszary Silverlight'a, które zapewne poszerzą się o dodatkowe funkcjonalności wraz z wyjściem wersji 5, jak również samego Windows 8.

Chętnych zapraszam do przeczytania artykułu:

"Microsoft to developers: Metro is your future" autorstwa Mary Jo Foley
(http://www.zdnet.com/blog/microsoft/microsoft-to-developers-metro-is-your-future/10611?tag=content;feature-roto)

Pod poniższym linkiem znajdziecie wykaz prezentacji, których wspólnym mianownikiem jest XAML
http://timheuer.com/blog/archive/2011/09/13/xaml-sessions-at-build.aspx

Samą konferencję Microsoft BUILD możecie śledzić pod adresem:
http://www.buildwindows.com/

piątek, 13 maja 2011

Silverlight 5 Markup Extension and Commanding

Last time, my college from my job told me that creation of ICommand implementation for every required element is very annoying for him and he would be happy if he could bind command (for ex. Button Click) directly to specific method.

As we know, there is not possible customize Markup Extension in Silverlight 4 because the IMarkupExtension interface has only internal access in this version.

Version 5 of Silverlight, extends ours horizons.

Below, I will show how we can achive our goal.

using System;
using System.Windows;
using System.Windows.Input;
using System.Xaml;
using Microsoft.Practices.Prism.Commands;

namespace CommandingSL5
{
    public class Commanding : IMarkupExtension<ICommand>
    {
        public string MethodName { get; set; }

        public ICommand ProvideValue(IServiceProvider serviceProvider)
        {
            if (!String.IsNullOrEmpty(MethodName))
            {
                if (serviceProvider == null)
                    return null;

                var rootService = (IRootObjectProvider)serviceProvider.GetService(typeof(IRootObjectProvider));
                var root = rootService.RootObject as FrameworkElement;
                if (root != null)
                {
                    if (root.DataContext != null)
                    {
                        var method = root.DataContext.GetType().GetMethod(MethodName);
                        if (method != null)
                        {
                            return new DelegateCommand(() => method.Invoke(root.DataContext, null));
                        }
                    }
                }
            }
            return null;
        }
    }
}

Interface IServiceProvider gives us possibility to get specific service which allows us access to target element (where was used our custom Markup Extension) or root element which is our View with associated ViewModel by property DataContext.

IRootObjectProvider: provide a reference to the Root object of the VisualTree which the element is part of
IXamlTypeResolver : is able to resolve the name of the tags in the markup to the corresponding type.
IProvideValueTarget : gets a reference to the property and the elements which the markup extension is assigned

(Source: Andrea Boschin Blog)

As we see, there is no problem to using more complex methods because I use .NET Reflection which gives me many possibilities.

Usage:
<UserControl x:Class="CommandingSL5.MainPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:c="clr-namespace:CommandingSL5" 
             mc:Ignorable="d">
    
    <UserControl.DataContext>
        <c:MainPageViewModel />
    </UserControl.DataContext>
        
    
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="150" />
        </Grid.ColumnDefinitions>
        
        <TextBox Text="{Binding MethodAText}" 
                 Margin="5,5" />
        <Button Content="Execute TestMethod A" 
                Command="{c:Commanding MethodName=TestMethodA}" 
                Margin="5,5"
                Grid.Column="1"/>
    </Grid>
</UserControl>


and also our ViewModel:

using System.ComponentModel;

namespace CommandingSL5
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        #region Fields
        private string _methodAText;
        #endregion

        #region Properties
        public string MethodAText
        {
            get { return _methodAText; }
            set
            {
                _methodAText = value;
                RaisePropertyChanged("MethodAText");
            }
        }
        #endregion

        #region Methods
        public void TestMethodA()
        {
            MethodAText = "TestMethodA executed !";
        }
        #endregion

        #region INotifyPropertyChanged Implementation
        public event PropertyChangedEventHandler PropertyChanged;

        public void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) 
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}