Vra

Update:Opgelos, met kode

Ek het dit werk, sien my antwoord hieronder vir die kode...

Oorspronklike Post

As Tundey uitgewys in sy antwoord na my laaste vraag, jy kan bind byna alles wat oor'n windows vorms beheer te ApplicationSettings redelik moeiteloos.So is daar werklik geen manier om dit te doen met die vorm, Grootte? Hierdie handleiding sê wat jy nodig het om te hanteer Grootte uitdruklik so jy kan red RestoreBounds in plaas van grootte, indien die venster is benut of tot die minimum beperk.Egter, ek het gehoop ek kan net gebruik om'n eiendom soos:

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

Maar ek kan nie sien nie'n manier om te bind dit in die ontwerper (Grootte is veral ontbreek uit die PropertyBinding lys).

Was dit nuttig?

Oplossing

Ek het uiteindelik met 'n vorm subklas dat hierdie los, eens en vir altyd. Om dit te gebruik:

  1. erf RestorableForm in plaas van vorm.
  2. Voeg 'n bindende in (ApplicationSettings) -> (PropertyBinding) om WindowRestoreState
  3. .
  4. Bel Properties.Settings.Default.Save () wanneer die venster is op die punt om te sluit.

Nou venster posisie en toestand sal onthou word tussen sessies. Na aanleiding van die voorstelle van ander plakkate hieronder, ingesluit ek 'n funksie ConstrainToScreen wat maak seker dat die venster pas mooi op die beskikbare uitstallings wanneer die herstel van self.

Kode

// 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);
        }
    }
}

Instellings Bindings Verwysings

Ander wenke

Die rede waarom die Vorm.Grootte van eiendom is nie beskikbaar in die instellings bindend UI is omdat hierdie eiendom is gemerk DesignerSerializationVisibility.Verborge.Dit beteken dat die ontwerper nie weet hoe om te serialise dit, laat staan genereer'n data bindend vir dit.In plaas daarvan om die Vorm.ClientSize eiendom is die een wat kry serialised.

As jy probeer en kry slim deur binding Plek en ClientSize, jy sal sien'n ander probleem.Wanneer jy probeer om te verander jou vorm uit die linker-of die boonste rand, sal jy sien vreemde gedrag.Dit is blykbaar wat verband hou met die manier wat twee-manier data bindend werk in die konteks van die eiendom stelle wat wedersyds beïnvloed mekaar.Beide Plek en ClientSize uiteindelik bel in'n algemene metode, SetBoundsCore().

Ook, data binding aan eienskappe soos Plek en Grootte is net nie doeltreffend.Elke keer as die gebruiker beweeg of die grootte van die vorm, Windows stuur honderde van boodskappe aan die vorm, wat veroorsaak dat die data bindend logika om te doen'n baie van die verwerking, wanneer al wat jy regtig wil hê, is om die laaste posisie en grootte voordat die vorm is gesluit.

Dit is'n baie vereenvoudigde weergawe van wat ek doen:

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;
} 

Waarom is hierdie'n baie vereenvoudigde weergawe?Want om dit te doen behoorlik is 'n baie moeiliker as dit lyk :-)

Wel, ek het 'n vinnige spel met hierdie het en jy is korrek, terwyl daar is geen manier om direk bind die grootte van die vorm om AppSettings, jy kan jou eie waardes te voeg en te verander die grootte op load.

Ek sou miskien beveel aan dat as dit 'n algemene verskynsel, jy oorerf Form en maak dit outomaties prob die App.Config vir die vorms grootte instellings.

(Of jy kan jou eie lêer rol .. Kry dit om 'n XML-lêer "formname.settings.xml" of iets navraag -! Dink hardop) ..

Hier is wat ek moes (baie grof, geen fout nagaan ens).

App.Config

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

Form Kode

    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);
    }

Een van die rede waarom ek dink grootte bindend is nie toegelaat is omdat die skerm kan verander tussen sessies.

laai die grootte terug toe die resolusie het verminder tot gevolg kan hê in die titel bar om buite die grense van die skerm.

Jy moet ook versigtig vir verskeie monitor setups, waar monitors nie meer beskikbaar kan wees om te wees wanneer jy app volgende lopies.

Ek stem saam met antwoord Rob Cooper se. Maar ek dink Martin maak 'n baie goeie punt. Niks soos om gebruikers jou aansoek en die app oop is off-skerm!

So in werklikheid, sal jy wil om beide antwoorde en hou in gedagte kombineer die huidige skerm dimensies voordat grootte van jou vorm.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top