Myślisz, że zarabiasz tyle, na ile zasługujesz? Zapraszamy do wzięcia udziału w anonimowej ankiecie.
1

Witam,

Próbuję wykorzystać kontrolkę System.Windows.Forms.PropertyGrid do ustawiania właściwości obiektu. Mój obiekt ma wiele właściwości które nie powinny być widoczne w tym okienku. Mój obiekt jest bindowany w programie.

Próbowałem nadać niechcianej właściwości atrybuty:


[Browsable(false)]
[Bindable(true)]


Zmiana widoczności właściwości działa dobrze ale pokazuje też się niechciany efekt uboczny a mianowicie, atrybut Browsable(false) powoduje że właściwość nie może być bindowana. Nigdzie w dokumentacji atrybutu nie znalazłem że takie jest jego zachowanie. Przeglądałem także inne fora w poszukiwaniu pomocy i nic. Wygląda na to że atrybut Browsable(false) poprostu ustawia Bindable na false i dlatego nie widać danej właściwości w PropertyGrid.

Jednym ze sposobów jaki na szybko przyszedł mi do głowy do nadanie odpowiedniej kategorii "chcianym" i "niechcianym" właściwościom i następnie przekazanie użytkownikowi informacji żeby korzystał z właściwości tylko z "chcianej" kategorii ale to jest baaardzo niefajne.

edit: Dodatkowo można dać atrybut ReadOnlyAttribute na "niechciane" właściwości ale to nadal jest niefajne.

Wydaje mi się że takie zachowanie to bug frameworka zwłaszcza że na w wersji 1.1 działa dobrze a w 2.0 już nie - na podstawie wpisu na social.msdn.microsoft.com/...

edit: Dodam jeszcze że zachowanie to się objawia gdy bindujemy coś do właściwości a nie właściwość do czegoś

Ma ktoś pomysł co robię źle albo co zrobić żeby działało tak jak chcę?

flag

2 Answers

1

W 3.5 [Browsable(false)] już działa... Zresztą po zmianie wersji frameworka na 2.0 też, przynajmniej u mnie.

public partial class Form1 : Form
{
  public Form1()
  {
    InitializeComponent();
  }

  private void Form1_Load(object sender, EventArgs e)
  {
    propertyGrid1.SelectedObject = new Foo();
  }
}

class Foo
{
  [Browsable(false)]
  public int Bar { get; set; }

  public int Baz { get; set; }
}

Zgodnie z oczekiwaniami w PropertyGridzie pojawia się jedynie właściwość Baz, Bar jest niewidoczny. U Ciebie zachowuje to się inaczej? Którą wersję frameworka masz ustawioną w projekcie, i w której wersji Visual Studio pracujesz?

EDIT:

Hmm, faktycznie pytanie nie było dla mnie do końca jasne. Jest tak jak mówisz - ustawienie atrybutu [Browsable(false)] na właściwości powoduje wyjątek przy próbie bindowania się do niej. Niestety nie jestem w stanie wymyślić jak zmienić zachowanie kontrolki i bindingu - większość metod, które wyglądały interesująco nie są wirtualne :/

EDIT:

Być może uda Ci się coś wypatrzeć debugując klasy .NET Frameworka.

link|flag
Nie zrozumiałeś problemu. Widoczność działa prawidłowo. Chodzi o to że po użyciu Browsable(false) nie można bindować właściwości czyli tak jakby Browsable(false) automatycznie ustawiało Bindable(false) – bodziec Jan 12 at 17:00
Faktycznie jak jeszcze raz przeczytałem moje pytanie to mój problem nie jest dobrze pokazany. Edytuje posta – bodziec Jan 12 at 17:03
0

Po konsultacjach na stackoverflow muszę zmienić podany przeze mnie przykład bo tamten akurat działa ;-) Udało mi się w końcu przenieść dokładnie kod jaki mam w głównym projekcie. Oto niedziałający przykład:


public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Data data = new Data();
            data.Text = "qwe";
            data.Width = 50;

            BindingSource bindingSource = new BindingSource();
            bindingSource.Add(data);

            textBox1.DataBindings.Add("Text", bindingSource, "Text", true, DataSourceUpdateMode.OnPropertyChanged);
            textBox1.DataBindings.Add("Width", bindingSource, "Width", true, DataSourceUpdateMode.OnPropertyChanged);

            dataGridView1.SelectedObject = data;
        }
    }

    public class Data : IBindableComponent
    {
        public event EventHandler TextChanged;
        private string _Text;
        [Browsable(true)]
        public string Text
        {
            get
            {
                return _Text;
            }
            set
            {
                _Text = value;
                if (TextChanged != null)
                    TextChanged(this, EventArgs.Empty);
            }
        }

        public event EventHandler WidthChanged;
        private int _Width;
        [Browsable(false)]
        public int Width
        {
            get
            {
                return _Width;
            }
            set
            {
                _Width = value;
                if (WidthChanged != null)
                    WidthChanged(this, EventArgs.Empty);
            }
        }

        #region IBindableComponent Members

        private BindingContext _BindingContext;
        public BindingContext BindingContext
        {
            get
            {
                if (_BindingContext == null)
                    _BindingContext = new BindingContext();

                return _BindingContext;
            }
            set
            {
                _BindingContext = value;
            }
        }

        private ControlBindingsCollection _DataBindings;
        public ControlBindingsCollection DataBindings
        {
            get 
            {
                if (_DataBindings == null)
                    _DataBindings = new ControlBindingsCollection(this);

                return _DataBindings;    
            }
        }

        #endregion

        #region IComponent Members

        public event EventHandler Disposed;

        public System.ComponentModel.ISite Site
        {
            get
            {
                return null;
            }
            set
            {

            }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        #endregion
    }

Po usunięciu atrybutu Browsable(false) na Data.Width program się nie wysypuje. Wygląda na to jakby BindingSource przeszukiwało datasource po atrybucie Browsable

link|flag

Your Answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.