October 2009 Blog Posts

WPF: SelectableTextBlock

24 October 2009 |

Вопрос: как в WPF вывести на экран текст, чтобы пользователь мог скопировать какую-либо его часть?

Вопрос получился чересчур общим, конкретизируем: есть ListBox, составной частью элементом которого должен быть контрол, позволяющий копировать отображаемый в нем текст. В  упрощенном виде можно считать, что ListBox показывает список таких контролов.

Первое что приходит в голову при решении такой задачи это взять обычный TextBox сделать его ReadOnly настроив по возможности его внешний вид. Сказано сделано, описание такого TextBox-а выглядит примерно вот так:

<TextBox IsReadOnly="True" MaxWidth="{Binding ElementName=listBox, Path=ActualWidth}" 
                             BorderThickness="0" Background="Transparent"
                             IsTabStop="False" AcceptsReturn="False" AcceptsTab="False"
                             Text="Some Text" FontSize="12" TextWrapping="Wrap" Margin="4,1,4,4"/>
 

Казалось бы живи и радуйся… но что это за жизнь без трудностей. Если делать клик на такой контрол, то соответствующий ему ListBoxItem не выделяется. Если этот контрол получит фокус, а для того чтобы выделять в нем текст он должен получить фокус, то навигация между ListBoxItem-ами по стрелочкам “вверх” - “вниз” не работает.

Что делать? Решение получилось не очень элегантным, но другого не придумалось, все дело в “потомке” для TextBox:

public class SelectableTextBlock : TextBox
{
    public SelectableTextBlock() : base()
    {
        this.AddHandler(SelectableTextBlock.KeyDownEvent, new KeyEventHandler(HandleHandledKeyDown), true);
    }
    
    public void HandleHandledKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Up || e.Key == Key.Down)
        {
            var keyEventArgs = new KeyEventArgs(e.KeyboardDevice, e.InputSource, e.Timestamp, e.Key)
            {
                RoutedEvent = e.RoutedEvent,
                Handled = false
            };
            (this.Parent as FrameworkElement).RaiseEvent(keyEventArgs);
        }
    }

    protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
    {
        base.OnPreviewMouseDown(e);

        var item = this.Parent as ListBoxItem;
        item.IsSelected = true;

        /* If Text Box defined in ListBox.Template
            var el= sender as FrameworkElement;
            var parent = VisualTreeHelper.GetParent(el);
            while (!(parent is ListBoxItem)) parent = VisualTreeHelper.GetParent(parent);
            var item = parent as ListBoxItem;
            item.IsSelected = true;             
         */
    }
}

Вот что значит, новая-универсальная технология с не устоявшимися практиками/шаблонами. Для решения такой, казалось бы ерундовой, задачи, приходиться прилагать ощутимые усилия.

В заключении стоит заметить, что под XBAP в таком виде решение не заработает по причине безопасности, new KeyEventArgs – не безопасный конструктор. Это можно обойти если “ручками” выделять нужный элемент при нажатии клавиш “вверх”-“вниз”.

Выборы: Новые технологии и “Тайна голосования”

11 October 2009 |

Москвичи, которые придут в это воскресенье на избирательные участки, смогут увидеть в действии новую технику для голосования. «Урны XXI века», или, официально, КОИБы — комплексы автоматической обработки избирательных бюллетеней. (ЦИК показал честные избирательные урны)

11 октября 2009 в Москве приходили выборы, не очень популярные среди населения, судя по официальным цифрам и личным наблюдениям. Но мы все таки решили принят в них участие, и как выяснилось позже не зря. Про политику, особенности проведения выборов, атмосферу и том подобные вещи говорить не будем…

На выборах встретил “автоматическую урну” - такой ящик пихаешь в него документ он твой голос учитывает, на дискетку пишет результат значит. Идея здравая, понятная и прозрачная, ну что в этом плохого, если бы не ее реализация.

При получении бюллетеня сразу говорят, что складывать его нельзя, иначе не обработает, понятно хорошо, что же… не совершенная технология, хрупкая технология, требует доработок. С другой стороны не так тяжело и донести листочек не помятым до урны.

Поразило то, что твориться у самой урны - торжество технологии (избирательных технологий). Рядом с этой урной стоит сотрудник, который берет из ваших рук заполненный бланк и засовывает в эту машину. Помним: листочек не свернут, пометка за кого голосуешь достаточно крупная – т.е. сотрудник прекрасно видит за кого ты проголосовал. Есть такое понятие как “Тайна голосования” это одно из ключевых понятий, во многом выборы организованы так как организованы именно из-за “тайны голосования”, вспомните такие ширмочки где заполняется бюллетень. Что сказать, ввели новую технологию, и ведь не просто ввели, а после тестовых испытаний.

Можно конечно, сказать что сотрудник не обращает внимание на выбор в бюллетенях, и можно его не считать человеком, а добавкой к “автоматической урне”, ну правильней тогда сказать к “автоматизированной урне”, у каждого свое мнение. Под конец могу сказать, что мой выбор был озвучен сотрудником вслух, достаточно громко, чтобы слышали окружающие… занавес.

Скорее всего не ошибусь, что, по мнению Центризбиркома, использование “автоматических урн” прошло в целом успешно, и технология готова и допустима для использования на президентских выборах.

Есть такое понятие Легитимность, к урнам это не относится. Для себя результаты прошедших выборов не считаю легальными и легитимными, почему… это уже тема совсем другого разговора.

Кто-то читает Библию

07 October 2009 |

Новость Ставропольский ученый пожаловался в прокуратуру на… Ветхий Завет, учитывая относительно недавнее знакомство с Библией и “святыми писаниями” других религий, никак нельзя оставить без внимания. Поражает, что выводы сделанные истицами удивительным образом согласуются с личными впечатлениям от прочтения Библии.

Можно было бы цитат подобрать и побольше и “поужасней” видно оставили на потом, судебный процесс предстоит долгий… Реакция “общества в усредненном виде” примерно такова: Религия и жизнь, т.е. недоуменная улыбка на лице. Объясняется это очень просто, мало людей читало Ветхий завет, если людям и хватает сил что-то прочитать, то только Новый завет.

Поэтому непонимание, не серьезное отношение, а ведь зря, единственное, что здесь можно найти “смешного”, что претензии по существу, очевидно справедливы, все действительно так…

Запретят ли Ветхий завет, ну конечно нет, для этого нужно, чтобы большинство его прочитало, самостоятельно не как пересказ кого-то, чтобы кроме всего этого большинство имело хотя бы среднее образование. Иначе всё будет упираться в вопрос Веры, ведь этому самому большинству, то что оно не читало Ветхий завет не мешает Верить что в нем нет ничего плохого.

Как бы то ни было, хорошо что поднесли зеркало, может быть глядя в зеркало будет проще увидеть “страшную морду”. Может быть кого-то это заставить задуматься, и не так безучастно относиться к “религиозному образованию”, которое вводиться в школах.

VS: Automatic Attach to Process…

07 October 2009 |

Вот такая жизненная ситуация: разрабатывается приложение, которое в ходе своей работы запускает процессы, которые основаны на коде разрабатываемом в том же решении.

Хорошо? Конечно нет, конечно плохо, что за корявая архитектура такая, нет таких причин чтобы надо было так делать… Но если уж можно что-то делать криво, так наверняка кто-то так сделает, так уж мир устроен. К чему же все это приводи, а к тому что код запущенный как отдельный процесс, не отлаживается, и дальше будет рассматриваться вопрос: что с этим делать?

Простой способ, после запуска процесса средствами VisualStudio: Debug –> Attach to Process… –> (в списке выбирается процесс и жмется кнопка Attach). Способ общий и понятный кому угодно. Недостаток, очень много рутинной работы, так каждый раз делать. К счастью его можно автоматизировать с помощью макроса:

Sub AttachToMyApp()
    Try
        Dim processes As EnvDTE.Processes = DTE.Debugger.LocalProcesses
        For Each proc As EnvDTE.Process In processes
            If proc.Name.Contains("MyApp.exe") Then
                proc.Attach()
            End If
        Next
    Catch ex As System.Exception
        MsgBox(ex.Message)
    End Try
End Sub

Можно настроить, чтобы он запускался сочетанием клавиш в Visual Studio после запуска процесса. Идею можно развить, после старта процесса, запускать код/процесс который каким либо хитрым образом подключается к VisualStudio и вызывает нужный макрос, тогда бы было вообще все автоматизировано, но сколько как это сделать и сколько сил придется потратить на реализацию такого решения.

VS + SetupProject + CustomAction + UAC = Problem

03 October 2009 |

Недавно товарищ пожаловался: если создать CustomAction в SetupProject VisualStudio 2008, то полученный таким образом инсталлятор будет выполнять это действие под правами: NT AUTHORITY\SYSTEM, если запущен на ОС поддерживающей UAC (User Account Control). Неприятная ситуация, если учесть что далеко не все действия может выполнять пользователь имеющий такие права, а учитывая что все равно пользователь вводит пароль администратора, то даже и удивительно почему бы не выполнять все действия с администраторскими привилегиями.

Проблема есть, насущна – требует решения. Удивительно но в интернете по этой теме не так много написано, а то что есть не дает внятного решения. Из того что есть, чтобы погрузиться в тему, рекомендую почитать:

Windows Installer Custom Actions, Windows Vista and Terminal Server

Custom Actions under UAC in Vista

Решение проблемы:

1. Открыть файл установщик VS: SetupXXX.vdproj в текстовом редакторе

2. Найти строчку: "RequiresElevation" = "11:FALSE" и изменить в ней значение на TRUE

Инсталлятор состоит из двух файлов: .exe и .msi, если пользователь будет запускать .exe то CustomAction будет выполнять под теми же правами что и сам инсталлятор, если .msi, то по прежнему как NT AUTHORITY\SYSTEM.

Исторически, технологии инсталляторов у Microsoft были “кривыми”, приходиться заметить что ничего не изменилось: “имидж ничто…”.