39 votes

WPF Databind Avant d'enregistrer

Dans mon application WPF, j'ai un certain nombre de zones de texte liées aux données. L' UpdateSourceTrigger de ces liaisons est - LostFocus. L'objet est enregistré à l'aide du menu Fichier. Le problème que j'ai, c'est qu'il est possible d'entrer une nouvelle valeur dans une zone de texte, sélectionnez Enregistrer dans le menu Fichier, et de ne jamais persister la nouvelle valeur (celui visible dans la zone de texte), car l'accès au menu ne permet pas de supprimer le focus dans la zone de texte. Comment puis-je résoudre ce problème? Est-il un moyen de forcer tous les champs d'une page à databind?

@palehorse: Bon point. Malheureusement, j'ai besoin d'utiliser LostFocus que mon UpdateSourceTrigger afin de soutenir le type de validation que je veux.

@dmo: j'avais pensé à ça. Il semble, cependant, comme un vraiment inélégante solution est relativement simple problème. En outre, il exige qu'il y ait un certain contrôle sur la page, qui est toujours visible à recevoir le focus. Ma demande est à onglets, toutefois, donc pas de contrôle facilement se présente.

@Nidonocu: Le fait qu'en utilisant le menu n'a pas de déplacer le focus dans la zone de texte qui me confond ainsi. C'est, toutefois, le problème que je vois. L'exemple simple suivant illustre mon problème:

<Window x:Class="WpfApplication2.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <ObjectDataProvider x:Key="MyItemProvider" />
    </Window.Resources>
    <DockPanel LastChildFill="True">
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="File">
                <MenuItem Header="Save" Click="MenuItem_Click" />
            </MenuItem>
        </Menu>
        <StackPanel DataContext="{Binding Source={StaticResource MyItemProvider}}">
            <Label Content="Enter some text and then File > Save:" />
            <TextBox Text="{Binding ValueA}" />
            <TextBox Text="{Binding ValueB}" />
        </StackPanel>
    </DockPanel>
</Window>
using System;
using System.Text;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication2
{
    public partial class Window1 : Window
    {
        public MyItem Item
        {
            get { return (FindResource("MyItemProvider") as ObjectDataProvider).ObjectInstance as MyItem; }
            set { (FindResource("MyItemProvider") as ObjectDataProvider).ObjectInstance = value; }
        }

        public Window1()
        {
            InitializeComponent();
            Item = new MyItem();
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(string.Format("At the time of saving, the values in the TextBoxes are:\n'{0}'\nand\n'{1}'", Item.ValueA, Item.ValueB));
        }
    }

    public class MyItem
    {
        public string ValueA { get; set; }
        public string ValueB { get; set; }
    }
}

26voto

BigBlondeViking Points 2455

J'ai trouvé que la suppression des éléments de menu qui sont la portée dépendait de la FocusScope du menu provoque la boîte à texte de perdre le focus correctement. Je ne pense pas que cela s'applique à tous les éléments dans menu, mais certainement pour une action enregistrer ou valider.

15voto

Dave the Rave Points 71

En supposant qu'il y ait plus d'un contrôle dans la séquence d'onglets, la solution suivante semble être complète et générale (juste couper et coller)...

8voto

rudigrobler Points 8883

Il s'agit d'un hack UGLY, mais devrait aussi fonctionner

Ce code vérifie si une TextBox a mise au point ... Si 1 est trouvé... mettre à jour la source de liaison!

6voto

rudigrobler Points 8883

Supposons que vous avez une zone de texte dans une fenêtre, et une Barre d'outils avec un bouton "Enregistrer" en elle. Assumer la zone de texte du Texte de propriété est lié à une propriété sur un objet d'entreprise, et la liaison du UpdateSourceTrigger propriété est définie sur la valeur par défaut de LostFocus, ce qui signifie que la valeur limite est repoussée à l'entreprise propriété de l'objet lorsque la zone de texte perd le focus d'entrée. Aussi, supposons que la Barre d'outils du bouton Enregistrer de la propriété Command a été mis à ApplicationCommands.Commande enregistrer.

Dans cette situation, si vous modifiez la zone de texte et cliquez sur le bouton Enregistrer avec la souris, il y a un problème. Lorsque vous cliquez sur un Bouton dans une Barre d'outils, la zone de texte ne pas perdre le focus. Depuis la zone de texte de l'événement LostFocus ne se déclenche pas, le Texte de la propriété de liaison de ne pas mettre à jour la source de la propriété de l'objet métier.

Évidemment, vous ne devriez pas valider et enregistrer un objet, le cas le plus récemment modifié la valeur dans l'INTERFACE utilisateur n'a pas encore été poussé dans l'objet. C'est le problème exact que Karl avait travaillé autour, par l'écriture de code dans la fenêtre qui recherchées manuellement pour une zone de texte avec l'accent et mis à jour la source de la liaison de données. Sa solution a bien fonctionné, mais il m'a fait penser à une solution générique qui sera également utile à l'extérieur de ce scénario particulier. Entrez CommandGroup...

Prises de Josh Smith article sur CodeProject CommandGroup

2voto

palehorse Points 8268

Avez-vous essayé de définir le UpdateSourceTrigger à PropertyChanged ? Alternativement, vous pouvez appeler la méthode UpdateSOurce(), mais cela semble un peu exagéré et va à l'encontre du but de TwoWay databinding.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X