2008-10-21 11 views
12

Mam okno WPF do edycji informacji z bazy danych, które jest reprezentowane za pomocą obiektu Entity Framework. Kiedy użytkownik zamknie okno, chciałbym zauważyć na zamknięciu, czy informacje się zmieniły i pokazać okno dialogowe oferujące zapisanie zmian w bazie danych.WPF: Zmiany w polu tekstowym z fokusem są zatwierdzane dopiero po tym, jak nastąpi zamknięcie zdarzenia.

Niestety, zmiany w aktualnie skupionej metodzie edycji nie są przypisywane do źródła wiązania, dopóki zmiana nie zostanie ustawiona, co ma miejsce w pewnym momencie po przetworzeniu zdarzenia zamknięcia.

Idealnie byłoby rutyna, która zatwierdza wszystkie zmiany w hierarchii widoku, które mógłbym wywołać przed sprawdzeniem, czy moja jednostka została zmodyfikowana. Szukałem również informacji na temat programowego usuwania fokusu z kontroli, ale nie wiem, jak to zrobić.

Moje pytanie brzmi: w jaki sposób jest to zwykle obsługiwane?

+0

podwójne pytanie: http://stackoverflow.com/questions/57493/ wpf-databind-before-saving # 229738 – Sam

+0

Kolejny sposób na rozwiązanie tego problemu: http://stackoverflow.com/a/17458095/194717 – Tony

Odpowiedz

7

To powinno cię całkiem blisko:



private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
{ 
    ForceDataValidation(); 
} 


private static void ForceDataValidation() 
{ 
    TextBox textBox = Keyboard.FocusedElement as TextBox; 

    if (textBox != null) 
    { 
     BindingExpression be = textBox.GetBindingExpression(TextBox.TextProperty); 
     if (be != null && !textBox.IsReadOnly && textBox.IsEnabled) 
     { 
      be.UpdateSource(); 
     } 
    } 

} 


+1

Sprawdziłem również, czy pole tekstowe zawiera zmiany: 'if ((textBox! = null) && (textBox.CanUndo)) {...} ' – jhr

0

Najprościej jest ustawić ostrość gdzieś. można z powrotem natychmiast ustawić ostrość, ale ustawianie ostrości w dowolnym miejscu wywoła LostFocus-Event na wszelkiego rodzaju kontroli i uczynić go aktualizować swoje rzeczy:

IInputElement x = System.Windows.Input.Keyboard.FocusedElement; 
DummyField.Focus(); 
x.Focus(); 

Innym sposobem byłoby dostać element skupiony, dostać element wiążący z elementu focused, i uruchom aktualizację ręcznie. Przykładem TextBox i ComboBox (trzeba by dodać dowolny typ sterowania trzeba wspierać):

TextBox t = Keyboard.FocusedElement as TextBox; 
if ((t != null) && (t.GetBindingExpression(TextBox.TextProperty) != null)) 
    t.GetBindingExpression(TextBox.TextProperty).UpdateSource(); 
ComboBox c = Keyboard.FocusedElement as ComboBox; 
if ((c != null) && (c.GetBindingExpression(ComboBox.TextProperty) != null)) 
    c.GetBindingExpression(ComboBox.TextProperty).UpdateSource(); 
1

Zakładając, że istnieje więcej niż jedna kontrola w sekwencji tabulatora, następujące rozwiązanie wydaje się być kompletny i ogólnie (tylko cut-and-paste) ...

Control currentControl = System.Windows.Input.Keyboard.FocusedElement as Control; 

if (currentControl != null) 
{ 
    // Force focus away from the current control to update its binding source. 
    currentControl.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); 
    currentControl.Focus(); 
} 
21

W WPF można zmienić Binding zaktualizować źródło na modyfikację, ignorując utraty ostrości. Odbywa się to poprzez ustawienie UpdateSourceTrigger nieruchomość do PropertyChanged:

Value="{Binding Path=MyProperty, UpdateSourceTrigger=PropertyChanged}" 
+0

Najlepsza odpowiedź, ponieważ jest to czysta metoda MVVM i nie wymaga zakłócania zdarzeń. Mimo to niesatysfakcjonujące, że nie jest to domyślny wyzwalacz, ponieważ wydaje mi się to najbardziej intuicyjnym dwukierunkowym zachowaniem ... – M463

3

Może trzeba usunąć ostrość od bieżącego elementu

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
{ 
    FocusManager.SetFocusedElement(this, null); 
} 
Powiązane problemy