воскресенье, 22 июня 2008 г.

WPF: MDI Окна. Часть вторая

Technorati Теги: ,

Johan спросил меня поддерживается ли MDI в Авалоне. Мы не планировали реализацию поддержки  MDI  в Авалоне версии 1, потому что MDI довольно легко реализовать средствами Windows Forms и Windows Forms interop. Я быстренько набросал небольшое демо, потратив слишком много времени чтобы в Авалоне картинка стала выглядеть более менее приемлемо, прежде чем я понял, что нет никакого способа выложить картинку в блог (гррр,гррр).
Первую вещь которую я закодил в Visual Studio, начал новый проект. Я создал простую Windows Form и задал значение IsMDIContainer = true. После я создал вторую Windows Form как дочернюю форму, и поместил в нее следующий код:

           Form f = new ChildForm();
            f.MdiParent = mainForm;
            f.Visible = true;

И это хорошо, но Авалон -- используем ElementHost. Я набросал перелестное меню и панель инструментов (креативно назвав "AvalonToolbar"), потом добавил некоторое количество кода в конструктор главного окна, чтобы поместить тулбар внутрь ElementHost, и поместить ElementHost внутрь окна:

            ElementHost host = new ElementHost();
            host.Dock = DockStyle.Top;
            host.Height = 71;

            // somewhat boneheaded way of getting Avalon content
            // into the ElementHost
            Page1 p = new Page1();
            FrameworkElement root = p.root;
            p.Child = null;
            host.AddChild(root);

            mainForm.Controls.Add(host);

Вполне возможно, лучше сделать root моего AvalonToolbar.xaml  Panel вместо Page, который поможет сохранить p.Root/p.Child = null, но по некоторым причинам я проявил упрямство. 
В итоге, я сделал несколько ElementHost в ChildForm, закрепляя разные блоки контекста Авалона внутри формы. И вуаля! MDI приложение в Авалоне с множеством тулбаров и дочерних окон. И все заняло минут пятнадцать, наибольшее время из этого ушло на изучение документации по свойству isMdiContainer (я не помню MdiParent, прошло пять лет с тех пор как я использовал WinForms).

WPF: Работа с MDI

Technorati Теги: ,

Открыв новый проект на WPF. Я обнаружил, что кудато делся мой любимый MDI - интерфейс. Недолгие поиски по интернету показали, что это все не случайно и сыр-бор идет еще с далекой первой версии "Авалона".

Lauren Lavoie в своем блоге отвечает на данный вопрос:(оригинал ответа тут)

Многие люди спрашивают почему в последнем билде WPF который мы зарелизили не включена поддержка MDI. С одной стороны, я хотел добавить это в версию 1. Но с другой стороны, я не представить себе причину по которой люди будут ждать пока мы наконецто не включим эту штуку в проект "как еще одну фичу".
Я действительно хочу сказать, что отсутствие поддержки MDI в WPF нисколько не подразумевает, что мы не думаем, что это важно. И при этом это не означает, что мы не можем добавить её в следующей версии, если не сделали её в первой версии. Есть несколько факторов, влияющих на это решение:

  • Отправляющий момент. Поскольку я уверен, что вы знаете, проекты программного обеспечения - всегда игра баланса. Баланса между одними возможностями и другими, между возможностями и патчами, между возможностью и датой выпуска продукта и т.д. MDI будет очень большой возможностью, если мы внедрим ее правильно (и разработка и внедрение подразумевает привлечение профессионалов выского класса, чтобы правильно интегрировать поддержку MDI  с существующим кодом управления стилями, системой свойств и т.д.) и в некоторой точке мы предстали перед выбором или добавить эту "большую фичу" или затянуть сроки сдачи проекта.
  • Шоколад или ваниль? Есть вероятно около двадцати "ароматов" MDI. Word делает MDI подругому чем Excel. Excel делает MDI не так как Visual Studio, а Visual Studio делает MDI совсем не так как FireFox. К томуже, я считаю, что tabbed browsing есть свой подвкус MDI. Фактически множество приложений используют своим разработки для MDI, потому что во вкусе предосталяемом API, чего не хватало каждому из разработчиков. Поэтому до того как разрабатывать, что-то такое монолитное как MDI, мы хотим удостовериться, что мы выбираем правильный аромат - или делаем это достаточно гибким способом так, чтобы наши разработчики могли настроить это, чтобы встретить их потребности. Я не думаю, что любой из нас действительно знает правильный способ сделать это все же - большая часть этого должна прибыть от понимания потребностей клиентов, которые фактически основываются на WPF (это - Вы, и следовательно спрашивать обратной связи в конце этого поста).

И так спросите вы, как же встаки использовать MDI  в вашем приложении. Не все потеряно как, кажется. Есть несколько простых способов лежащих на поверхности, годящихся на то, чтобы обойти ограничения.

  1. Использовать "Windows Forms interop". Ник Крамер описывает способ сделать это с примерами кода в своем блоге
  2. Сделать это самим. Что не так сложно как кажеться. Факт, множество приложений уже делают это сегодня, потому что их собственный вкус MDI пришел от прямоугольника в Win32/MFC/WinForms. AvPad Криса Андерсона демонстрирует менеджер дочерних окон, и Крис заявляет что его было не так сложно делать.

суббота, 21 июня 2008 г.

проба нового софта

Technorati Теги:

Установил себе новую программулину Windows Live Write. Вроде бы как обещано, оно сможет помогать делать постинги на мой любимый блог.

Ну чтож. Проверим-с. :)

З.Ы.Ж. Оказалось вполне приемлимо.

пятница, 20 июня 2008 г.

XAML: текст и картинка в кнопке

В XAML разметке по правилам можно указать только один элемент контекста для кнопки. Или текст или картинку. Но не все так плохо, как кажеться, если воспользоваться контейнерным элементом (Grid,StackPanel etc)

В итоге пример разметки будет подобным:

<Button Name="button2">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16" />
<ColumnDefinition Width="92*" />
</Grid.ColumnDefinitions>
<Image Name="image2" Source="/ТДТ;component/Img/Close.png" Stretch="Fill" />
<TextBlock Grid.Column="1" Name="textBlock2" Text="Закрыть"/>
</Grid>

</Button>

Ангел

четверг, 19 июня 2008 г.

Начало

После долгих странствий по дневниковым хостерам, я наконецто завел себе собственный отдельный огородик. :)