MSDN подписка: если "не работает" WISMO

среда, 19 августа 2009 г.,

На странице Account Overview есть ссылка Shipment Information, переход по которой ведет на страницу "WISMO - Where Is My Order?", но может привести на страницу с сообщением об ошибке.
Решение: в главном меню IE надо выбрать Tools - Internet Options - Languages и в начало списка Language поставить "English (United States) [en-US]".

Платформа 2010

вторник, 11 августа 2009 г.,

Открыт сайт 11-ой ежегодной конференции "Платформа 2010". На конференции будут представлены продукты: Microsoft Expression, Microsoft Silverlight 3.0, Microsoft Office 2010, Microsoft Exchange Server 2010, Windows 7, Microsoft Visual Studio 2010, Windows Server 2008 R2. Наверное, будет и Bing, хотя про него на сайте не сказано.
Конференция расчитана на 1500 посетителей (30% IT-директора, 30% IT-профессионалы, 20% разработчики + вся возможная ИТ-пресса).
Если вам (хостеры, веб-студии, web VAR'ы, SaaS-провайдеры...) требуется стенд на конференции - обращайтеся к Диденко.

Официальный блог конференции "Платформа".
Twitter.

XAML-> PNG | GIF | JPG | ...

понедельник, 27 июля 2009 г.,

Из XAML можно получить изображение в формате PNG, GIF, JPG. Ниже пример создания PNG-файла.
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

public class XamlHelper
{
    public static void SaveToPNG(FrameworkElement fe, string fname)
    {
        var bitmap = new RenderTargetBitmap((int)fe.ActualWidth, (int)fe.ActualHeight, 96, 96, PixelFormats.Pbgra32);
        bitmap.Render(fe);
        BitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmap));
        using (Stream stream = File.Create(fname))
            encoder.Save(stream);
    }
}

Также можно создать: GIF - с помощью GifBitmapEncoder, JPG - JpegBitmapEncoder.

P.S.
код можно использовать в WinForms приложении или обычной Class Library. Для этого к проекту необходимо подключить следующие сборки:
C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll
C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.dll
C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationCore.dll

Как найти свободный порт

пятница, 24 июля 2009 г.,

На codeproject случайно обнаружил способ выявления свободного порта:
public static int FindPort()
{
    IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
    using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
    {
        socket.Bind(endPoint);
        IPEndPoint local = (IPEndPoint)socket.LocalEndPoint;
        return local.Port;
    }
}
Другой способ здесь.

Работа с метаинформацией

четверг, 16 июля 2009 г.,

Метаинформация или метаданные - это информация об информации или другими словами - дополнительная информация. Например, есть следующее перечисление:
public enum Test
{
    First,
    Second,
    Third
}
Требуется добавить метаданные к элементам перечисления. Сделать это можно с помощью атрибутов.
Например, к каждому элементу можно добавить его описание с помощью атрибута Description:
public enum Test
{
    [Description("First Element")]
    First,
    [Description("Second Element")]
    Second,
    [Description("Third Element")]
    Third
}
Надо заметить, что Description - это краткая форма DescriptionAttribute (т.е. Attribute можно не указывать).
Для того чтобы прочитать значение DescriptionAttribute.Description, который определен у Test.Second, надо вызвать метод GetDescription:
var description = Test.Second.GetDescription();
Метод является extension method'ом; далее приводится его реализация:
public static class EnumerationExtension
{
    public static string GetDescription(this Enum value)
    {
        var da = GetAttribute<DescriptionAttribute>(value);
        return da != null ? da.Description : string.Empty;
    }

    public static A GetAttribute<A>(this Enum value) where A : Attribute
    {
        var type = value.GetType();
        var name = Enum.GetName(type, value);
        var field = type.GetField(name);
        return field.GetCustomAttributes(typeof(A), true).Cast<A>().FirstOrDefault();
    }
}
P.S.
если требуется по Descriptor'у найти соответствующее значение перечисления, то надо вызвать метод FindValue:
Test res;
if (EnumExtention.FindValue<Test>("Second Element", out res))
{
    // ...
}
Ниже приводится реализация метода:
public static class EnumExtention
{
    public static bool FindValue<E>(string description, out E ret)
    {
        var type = typeof(E);
        foreach (var item in Enum.GetNames(type))
        {
            var da = GetAttribute<DescriptionAttribute>(type, item);
            if (da != null && string.Equals(da.Description, description, StringComparison.OrdinalIgnoreCase))
            {
                ret = (E)Enum.Parse(type, item);
                return true;
            }
        }
        ret = default(E);
        return false;
    }

    public static A GetAttribute<A>(Type type, string fieldName)
    {
        var field = type.GetField(fieldName);
        return field.GetCustomAttributes(typeof(A), true).Cast<A>().FirstOrDefault();
    }
}

Как получить Action по имени метода

среда, 15 июля 2009 г.,

Есть класс, в котором определен метод Test, например:
public class MyClass
{
    public void Test()
    {
    }
}
Чтобы получить Action на основе имени метода Test надо выполнить следующий код:
var mc = new MyClass();
var a = mc.CreateAction("Test");
a(); // будет вызван метод Test
Весь "секрет" находится в методах расширения:
public static class MetodInfoExtension
{
    public static Action CreateAction(this object instance, string methodName)
    {
        return instance.GetType().GetMethod(methodName).CreateAction(instance);
    }

    public static Action CreateAction(this MethodInfo methodInfo, object target)
    {
        var call = System.Linq.Expressions.Expression.Call(System.Linq.Expressions.Expression.Constant(target), methodInfo);
        var lambda = System.Linq.Expressions.Expression.Lambda<Action>(call);
        var ret = lambda.Compile();
        return ret;
    }
}
В остальных случаях можно создать Action с помощью следующих строк:
Expression<Action> exa = () => Test();
Action a = exa.Compile();

WPF: загрузка html в WebBrowser из ресурсов


Есть следующий xaml, в котором определен WebBrowser:
<Window x:Class="WpfApplication6.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
  <WebBrowser x:Name="_Wb" Margin="20" />
</Window>
Требуется загрузить в WebBrowser содержимое файла, например, Content.htm, который добавлен в проект как ресурс (т.е. в свойствах файла указан Build Action: Resource).
Для этого в конструктор класса Window1 надо добавить следующий код:
Uri uri = new Uri(@"pack://application:,,,/Content.htm", UriKind.Absolute);
Stream source = Application.GetResourceStream(uri).Stream;
_Wb.NavigateToStream(source);

P.S.
Ресурсный файл Content.htm можно сделать "подфайлом" для Window.xaml, т.е. Content.htm станет соседом для Window.xaml.cs; для этого надо в файле проекта (файл с расширением .csproj) заменить
<Resource Include="Window1.htm" />
на
<Resource Include="Window1.htm">
    <DependentUpon>Window1.xaml</DependentUpon>
</Resource>
В Visual Studio в появившемся диалоге "File Modification Detected" нажать Reload.