[ DarkMan @ 01.03.2008. 02:27 ] @
Sledi kod primera koji demonstrira moj problem (ceo program je i u attachment-u):
Code:


using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication1
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainWindow());
        }      
    }

    public class MainWindow: Form
    {
        public MainWindow()
        {
            PropertyGrid grid = new PropertyGrid();
            grid.Dock = DockStyle.Fill;
            this.Size = new Size(200, 300);
            this.Controls.Add(grid);
            this.StartPosition = FormStartPosition.CenterScreen;

            TestContainer test = new TestContainer();
            test.Arguments.Add(new Argument());
            grid.SelectedObject = test;

        }
    }

    public class TestContainer
    {
        private ArgumentCollection m_Arguments = new ArgumentCollection();

        public ArgumentCollection Arguments
        {
            get { return m_Arguments; }
            set { m_Arguments = value; }
        }
    }

    public class ArgumentCollection: CollectionBase
    {
        public void Add(Argument arg)
        {
            this.List.Add(arg);
        }
        public void Remove(Argument arg)
        {
            this.List.Remove(arg);
        }

        public Argument this[int index]
        {
            get { return (Argument)this.List[index]; }
        }
    }

    public class Argument
    {
        private string m_Name;
        private SqlDbType m_Type;

        [Description("Argument Name")]
        public string Name
        {
            get { return m_Name; }
            set { m_Name = value; }
        }

        [Description("Argument Type")]
        public SqlDbType Type
        {
            get { return m_Type; }
            set { m_Type = value; }
        }

        public Argument(string name, SqlDbType type)
        {
            this.m_Name = name;
            this.m_Type = type;
        }

        public Argument(Argument p)
            : base()
        {
            if(p != null) {
                this.m_Name = p.m_Name;
                this.m_Type = p.m_Type;
            }
        }

        public Argument()
        {
            this.m_Name = "";
            this.m_Type = SqlDbType.VarChar;
        }
    }


}


Kada se pokrene program i klikne na dugme '...' za editovanje kolekcije Argumenata prikaze se dijalog standardnog CollectionEditor-a. Ako sad promenimo neki bilo koji property prvog clana pa zatim kliknemo na Cancel i onda ponovo pokrenemo CollectionEditor, videcemo da je promena zapamcena iako smo kliknuli na Cancel.
U slucaju da je dodat novi clan pa kliknut Cancel ta promena nece biti zapamcena.

U cemu je ovde problem? Da li nisam dobro napisao kolekciju ili nesto nije u redu sa CollectionEditor-om?


[ mmix @ 02.03.2008. 16:11 ] @
Ti si dobro napisao kolekciju i ispunjavas tri minimalna uslova neophodna da bi collection bio editovan kroz collectionEditor. Ovo je jednostavno nacin na koji collection editor radi, Cancel se odnosi samo na brisanje i dodavanje novih elemenata, samo promene nad zivim instancama su trenutne.

Ne znam kako bi ovo mogao da resis sem da mozda napravis svoj Collection editor i zakacis ga za TestContainer.Arguments sa [EditorAttribute] i onda u svojoj implementaciji collection editora obezbedis rollback.
[ DarkMan @ 02.03.2008. 20:13 ] @
Procitao sam jedan tekst gde je takodje receno da tako radi CollectionEditor.
Napisao sam svoj CollectionEditor koji, u slucaju Cancel-a, moze da vrati svojstva kolekcije u pocetno stanje.

Takodje problem kod koriscenja CollectionEditor-a u PropertyGrid-u je to sto se posle izmene kolekcije PropertyGrid ne vraca informaciju o promeni preko PropertyValueCanged eventa. Ovo sam resio takodjem koriscenjem svog collection editora, koji mi vraca informaciju o promeni, pa ako je izvrsena promena rucno pozovem sve registrovane metode PropertyValueCanged eventa.