Обходной путь для UpdateSourceTrigger LostFocus в Silverlight Datagrid? - PullRequest
5 голосов
/ 31 октября 2008

У меня есть приложение Silverlight 2, которое проверяет данные OnTabSelectionChanged. Сразу же я начал желать, чтобы UpdateSourceTrigger допускал больше, чем просто LostFocus, потому что если вы щелкаете вкладку без вкладки элемента управления, объект LINQ не обновляется до проверки.

Я обошел проблему с TextBoxes, установив фокус на другой элемент управления, а затем снова включил OnTextChanged:

Private Sub OnTextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
    txtSetFocus.Focus()
    sender.Focus()
End Sub

Теперь я пытаюсь осуществить такой же взлом в DataGrid. Моя DataGrid использует DataTemplates, сгенерированные во время выполнения для CellTemplate и CellEditingTemplate. Я пытался записать TextChanged = "OnTextChanged" в TextBox в DataTemplate, но он не срабатывает.

У кого-нибудь есть идеи?

Ответы [ 4 ]

7 голосов
/ 15 июля 2010

Вы можете сделать это с помощью поведения, примененного к текстовому полю

// xmlns:int is System.Windows.Interactivity from System.Windows.Interactivity.DLL)
// xmlns:behavior is your namespace for the class below
<TextBox Text="{Binding Description,Mode=TwoWay,UpdateSourceTrigger=Explicit}">
    <int:Interaction.Behaviors>
       <behavior:TextBoxUpdatesTextBindingOnPropertyChanged />
    </int:Interaction.Behaviors>
</TextBox>


public class TextBoxUpdatesTextBindingOnPropertyChanged : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.TextChanged += new TextChangedEventHandler(TextBox_TextChanged);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        AssociatedObject.TextChanged -= TextBox_TextChanged;
    }

    void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        var bindingExpression = AssociatedObject.GetBindingExpression(TextBox.TextProperty);
        bindingExpression.UpdateSource();
    }
}
0 голосов
/ 26 мая 2010

В этом посте блога показано, как явно обновить источник текстового поля с помощью вложенного свойства: http://www.thomasclaudiushuber.com/blog/2009/07/17/here-it-is-the-updatesourcetrigger-for-propertychanged-in-silverlight/

Вы можете легко изменить его для работы с другими элементами управления ...

0 голосов
/ 20 июня 2010

Я столкнулся с этой же проблемой, используя MVVM и Silverlight 4. Проблема в том, что привязка не обновляет источник до тех пор, пока текстовое поле не потеряет фокус, но установка фокуса на другом элементе управления не поможет.

Я нашел решение, используя комбинацию двух разных постов в блоге. Я использовал код из концепции DefaultButtonHub Патрика Колдуэлла с одним «SmallWorkaround» из SmallWorkarounds.net

http://www.cauldwell.net/patrick/blog/DefaultButtonSemanticsInSilverlightRevisited.aspx

www.smallworkarounds.net / 2010/02 / elementbindingbinding-modes.html

Мое изменение привело к следующему коду для класса DefaultButtonHub:

public class DefaultButtonHub
{
    ButtonAutomationPeer peer = null;

    private void Attach(DependencyObject source)
    {
        if (source is Button)
        {
            peer = new ButtonAutomationPeer(source as Button);
        }
        else if (source is TextBox)
        {
            TextBox tb = source as TextBox;
            tb.KeyUp += OnKeyUp;
        }
        else if (source is PasswordBox)
        {
            PasswordBox pb = source as PasswordBox;
            pb.KeyUp += OnKeyUp;
        }
    }

    private void OnKeyUp(object sender, KeyEventArgs arg)
    {
        if (arg.Key == Key.Enter)
            if (peer != null)
            {
                if (sender is TextBox)
                {
                    TextBox t = (TextBox)sender;
                    BindingExpression expression = t.GetBindingExpression(TextBox.TextProperty);
                    expression.UpdateSource();
                }
                ((IInvokeProvider)peer).Invoke();
            }
    }

    public static DefaultButtonHub GetDefaultHub(DependencyObject obj)
    {
        return (DefaultButtonHub)obj.GetValue(DefaultHubProperty);
    }

    public static void SetDefaultHub(DependencyObject obj, DefaultButtonHub value)
    {
        obj.SetValue(DefaultHubProperty, value);
    }

    // Using a DependencyProperty as the backing store for DefaultHub.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DefaultHubProperty =
        DependencyProperty.RegisterAttached("DefaultHub", typeof(DefaultButtonHub), typeof(DefaultButtonHub), new PropertyMetadata(OnHubAttach));

    private static void OnHubAttach(DependencyObject source, DependencyPropertyChangedEventArgs prop)
    {
        DefaultButtonHub hub = prop.NewValue as DefaultButtonHub;
        hub.Attach(source);
    }

}

Это должно быть включено в какую-то документацию для Silverlight:)

0 голосов
/ 31 октября 2009

Я знаю, что это старые новости ... но я справился с этим, сделав следующее:

Text = "{Binding Path = newQuantity, UpdateSourceTrigger = PropertyChanged}"

...