Question

Mise à jour:Résolu, avec le code

J'ai eu de travail, voir ma réponse ci-dessous pour le code...

Post Original

Comme Tundey souligné dans sa réponse à mon dernière question, vous pouvez lier à peu près tout sur un contrôle windows forms à ApplicationSettings assez facilement.Donc, il y a vraiment aucun moyen de le faire avec la Taille du formulaire? Ce tutoriel dit que vous avez besoin pour gérer la Taille explicitement de sorte que vous pouvez enregistrer RestoreBounds au lieu de la taille, si la fenêtre est agrandie ou réduite.Cependant, j'espérais que je pourrais simplement utiliser une propriété comme:

public Size RestoreSize
{
    get
    {
        if (this.WindowState == FormWindowState.Normal)
        {
            return this.Size;
        }
        else
        {
            return this.RestoreBounds.Size;
        }
    }
    set
    {
        ...
    }
}

Mais je ne peux pas voir un moyen de lier ce que le concepteur (la Taille est notamment absente de la PropertyBinding liste).

Était-ce utile?

La solution

Je suis arrivé finalement à une Forme de sous-classe qui permet de résoudre ce, une fois pour toutes.Pour l'utiliser:

  1. Hériter de RestorableForm au lieu de la Forme.
  2. Ajouter une liaison en (ApplicationSettings) -> (PropertyBinding) à WindowRestoreState.
  3. Propriétés De L'Appel.Les paramètres.Par défaut.Save() lorsque la fenêtre est sur le point de fermer.

Maintenant, la position de la fenêtre et de l'état seront rappelés entre les sessions.En suivant les suggestions des autres affiches ci-dessous, j'ai inclus une fonction ConstrainToScreen qui fait en sorte que la fenêtre s'intègre parfaitement sur le disponible s'affiche lors de la restauration elle-même.

Code

// Consider this code public domain. If you want, you can even tell
// your boss, attractive women, or the other guy in your cube that
// you wrote it. Enjoy!

using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;

namespace Utilities
{
    public class RestorableForm : Form, INotifyPropertyChanged
    {
        // We invoke this event when the binding needs to be updated.
        public event PropertyChangedEventHandler PropertyChanged;

        // This stores the last window position and state
        private WindowRestoreStateInfo windowRestoreState;

        // Now we define the property that we will bind to our settings.
        [Browsable(false)]        // Don't show it in the Properties list
        [SettingsBindable(true)]  // But do enable binding to settings
        public WindowRestoreStateInfo WindowRestoreState
        {
            get { return windowRestoreState; }
            set
            {
                windowRestoreState = value;
                if (PropertyChanged != null)
                {
                    // If anybody's listening, let them know the
                    // binding needs to be updated:
                    PropertyChanged(this,
                        new PropertyChangedEventArgs("WindowRestoreState"));
                }
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            WindowRestoreState = new WindowRestoreStateInfo();
            WindowRestoreState.Bounds
                = WindowState == FormWindowState.Normal ?
                  Bounds : RestoreBounds;
            WindowRestoreState.WindowState = WindowState;

            base.OnClosing(e);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (WindowRestoreState != null)
            {
                Bounds = ConstrainToScreen(WindowRestoreState.Bounds);
                WindowState = WindowRestoreState.WindowState;
            }
        }

        // This helper class stores both position and state.
        // That way, we only have to set one binding.
        public class WindowRestoreStateInfo
        {
            Rectangle bounds;
            public Rectangle Bounds
            {
                get { return bounds; }
                set { bounds = value; }
            }

            FormWindowState windowState;
            public FormWindowState WindowState
            {
                get { return windowState; }
                set { windowState = value; }
            }
        }

        private Rectangle ConstrainToScreen(Rectangle bounds)
        {
            Screen screen = Screen.FromRectangle(WindowRestoreState.Bounds);
            Rectangle workingArea = screen.WorkingArea;

            int width = Math.Min(bounds.Width, workingArea.Width);
            int height = Math.Min(bounds.Height, workingArea.Height);

            // mmm....minimax
            int left = Math.Min(workingArea.Right - width,
                                Math.Max(bounds.Left, workingArea.Left));
            int top = Math.Min(workingArea.Bottom - height,
                                Math.Max(bounds.Top, workingArea.Top));

            return new Rectangle(left, top, width, height);
        }
    }
}

Les Paramètres De Liaisons De Références

Autres conseils

La raison pour laquelle la Forme.La taille de la propriété n'est pas disponible dans les paramètres de liaison de l'INTERFACE utilisateur est parce que cette propriété est marqué DesignerSerializationVisibility.Caché.Cela signifie que le concepteur ne sais pas comment serialise et, a fortiori, de générer une liaison de données pour cela.Au lieu de la Forme.ClientSize la propriété est celle qui est sérialisé.

Si vous essayez d'obtenir le malin en liaison Emplacement et ClientSize, vous verrez un autre problème.Lorsque vous essayez de redimensionner votre formulaire à partir de la gauche ou du haut, vous verrez des comportements bizarres.C'est apparemment lié à la façon dont les deux sens de la liaison de données dans le cadre de jeux de propriétés que l'incidence les uns sur les autres.Les deux Emplacement et ClientSize finalement appel à une méthode commune, SetBoundsCore().

Aussi, la liaison de données de propriétés comme la Emplacement et Taille n'est tout simplement pas efficace.Chaque fois que l'utilisateur se déplace ou redimensionne la forme, Windows envoie des centaines de messages de la forme, causant la logique de liaison de données à faire beaucoup de traitement, quand tout ce que vous voulez vraiment est de stocker la dernière position et la taille avant que le formulaire est fermé.

C'est une version très simplifiée de ce que je fais:

private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
    Properties.Settings.Default.MyState = this.WindowState;
    if (this.WindowState == FormWindowState.Normal)
    {
       Properties.Settings.Default.MySize = this.Size;
       Properties.Settings.Default.MyLoc = this.Location;
    }
    else
    {
       Properties.Settings.Default.MySize = this.RestoreBounds.Size;
       Properties.Settings.Default.MyLoc = this.RestoreBounds.Location;
    }
    Properties.Settings.Default.Save();
}

private void MyForm_Load(object sender, EventArgs e)
{
    this.Size = Properties.Settings.Default.MySize;
    this.Location = Properties.Settings.Default.MyLoc;
    this.WindowState = Properties.Settings.Default.MyState;
} 

Pourquoi est-ce une version très simplifiée?Parce que faire cela correctement est beaucoup plus compliqué qu'il n'y paraît :-)

Eh bien, j'ai eu un coup de jouer avec cela et que vous êtes correct, même s'il est impossible de directement lier la taille de la forme de AppSettings, vous pouvez ajouter vos propres valeurs et de modifier la taille de la charge.

J'aurais peut-être recommander que si c'est une caractéristique commune, vous sous-classe de Formulaire et de le faire automatiquement problème de l'Application.Config pour les formes les paramètres de taille.

(Ou vous pouvez rouler votre propre fichier..Obtenez la requête d'un fichier Xml "formname.settings.xml" ou quelque chose?- thinking out loud!)..

Voici ce que j'ai eu (très approximatif, pas de contrôle d'erreur, etc).

App.Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key ="FormHeight" value="500" />
        <add key ="FormWidth" value="200"/>
    </appSettings>
</configuration>

Le Code Du Formulaire

    private void Form1_Load(object sender, EventArgs e)
    {
        string height = ConfigurationManager.AppSettings["FormHeight"];
        int h = int.Parse(height);
        string width = ConfigurationManager.AppSettings["FormWidth"];
        int w = int.Parse(width);
        this.Size = new Size(h, w);
    }

L'une des raisons pour lesquelles j'imagine la taille de liaison n'est pas autorisé est parce que l'écran peut changer entre les sessions.

Chargement de la taille arrière lorsque la résolution est réduite pourrait entraîner dans la barre de titre d'être au-delà des limites de l'écran.

Vous avez également besoin de se méfier des moniteurs multiples configurations, où les moniteurs peuvent ne plus être disponibles lorsque vous application exécute ensuite.

Je suis d'accord avec Rob Cooper réponse.Mais je pense que Martin a fait un très bon point.Rien de tel que les utilisateurs d'ouvrir votre application et de l'application est hors de l'écran!

Donc, en réalité, vous aurez envie de combiner à la fois des réponses et des ours à l'esprit l'actuel dimensions de l'écran avant de mettre votre formulaire de taille.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top