Тэги

Silverlight (36) WPF (10) IIS (7) Visual Studio (7) SharePoint (6) .Net Framework (5) ODP.NET (5) ASP.NET (4) C# (4) common (4) Network Settings (3) JavaScript (2) MS Office (2) Resharper (2) WCF (2) WEB (2) XPath (2) XSLT (2) ADO.NET (1) APEX (1) CMD (1) CSS (1) EF (1) HTML (1) Hardware bugs (1) Java (1) MS SQL (1) Oracle (1) PDF (1) Version Control (1) XAML (1)

понедельник, 14 декабря 2009 г.

Silverlight 3: UpdateSourceTrigger PropertyChanged – реализация отсутствующего функционала



В Silverlight 3 для UpdateSourceTrigger есть только занчения Default и Explicit.
Часто необходимо получить WPF поведение – UpdateSourceTrigger . PropertyChanged

Как это решается:
В лоб:
Вешаем на TextBox обраотчик TextChanged в котором передергиваем фокус на элементе. Стандартная фишка и работает без потери позиции курсора в Silverlight.

private void MyTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    // чтоб работало вточности как при WPF UpdateSourceTrigger.PropertyChanged реагируем только если элемент под фокусом
    // Т.е. этим запретим установку фокуса при отркрытии
    if (FocusManager.GetFocusedElement() != sender)
    {
        return;
    }

    // здесь ставьте фокус на какой-то невидимый элемент или на RootVisual
    UiUtilsCommon.TrySetFocusOnRootVisual();

    var tb = sender as TextBox;

    // возвращаем фокус
    tb.Focus();
}

Как это решается по уму:
Создавайте в коде свой контрол, который наследует TextBox и подкллючите приведенный выше обработчик в конструкторе.

Для PasswordBox:
Для PasswordBox это проще решается в лоб через переопределение PasswordChanged, т.к. класс PasswordBox помечен как sealed. Можно, конечно, заморочиться на композитный контрол, но это лишнее.

private void MyPasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
    if (FocusManager.GetFocusedElement() != sender)
    {
        return;
    }    UiUtilsCommon.TrySetFocusOnRootVisual();    var thisPasswordBox = sender as PasswordBox;    thisPasswordBox.Focus();
}Проблема. Когда возникает:
У вас есть список (дерево, грид и т.д.) элементов, а также детальная область, заполняемая биндингом по выбранному элементу и позволяющая редактировать выделенный элемент.
Производим изменение только в одном поле (TextBox) и, не убирая с него фокус, сразу выбираем другой элемент в списочном элементе.
В этом случае вы потеряете изменение, а также не сможете отреагировать и выполнить какую-то вашу важную логику.
При выборе другого элемента у вас уже отображаются другие данные.
При наступлении события выбора другого элемента биндинг по TextBox еще не отработал и новое значение поля в низлежащем объекте не будет задано.

Источник:
Textbox - how to update source object without losing focus?
Там есть и другие идеи.

Комментариев нет:

Отправить комментарий