BindingSource / BindingNavigator: как предотвратить редактирование связанного источника данных?

Я создал источник данных с помощью VB.NET и Visual Studio 2005. Я перетащил источник данных в свой диалог, и VS создал текстовые поля с членами моего связанного объекта, System.Windows.Forms.BindingSource и System.Windows.Forms.BindingNavigator.

Я заполняю список (называемый myList), устанавливаю myList в качестве источника данных в BindingSource, и все работает отлично, за исключением того факта, что я хочу, чтобы он был доступен только для чтения. Если пользователь что-то меняет в одном из текстовых полей, он сохраняет изменения.

Я попытался создать коллекцию только для чтения для привязки к BindingSource, но это не решило проблему:

Dim detailsDlg As New dlgMyDetails
Dim readOnlyList As New ReadOnlyCollection(Of MyObjects)(myList)

detailsDlg.MyBindingSource.DataSource = readOnlyList
detailsDlg.ShowDialog()

Думаю, я мог бы отключить все текстовые поля, но это кажется немного неуклюжим, плюс я, вероятно, захочу изменить цвет шрифта, чтобы его было легче читать.

В идеале мне, вероятно, было бы все равно, если бы пользователи могли устанавливать фокус на текстовые поля или даже редактировать содержимое, но я просто не хотел бы, чтобы какие-либо изменения сохранялись. То есть, если кто-то что-то отредактировал, с помощью навигатора перешел к следующей записи, а потом вернулся, я бы хотел, чтобы было так, как было до того, как пользователь с этим поигрался.

Любые предложения / рекомендации?

Заранее спасибо!


person John    schedule 11.02.2010    source источник


Ответы (2)


С точки зрения модели-представления-управления желаемое ограничение касается не модели или элемента управления, а представления. Представление должно ограничивать то, что можно редактировать на экране.

Если он действительно доступен только для чтения, почему бы не использовать элемент пользовательского интерфейса только для чтения, т. е. метку? Причина, по которой вы это делаете, состоит в том, чтобы уменьшить путаницу для пользователя. Если это текстовое поле, разумно ожидать, что в какой-то момент данные станут редактируемыми. Если это не так, то представление отключенного текстового поля, скорее всего, не является правильным элементом пользовательского интерфейса для представления, а, как уже упоминалось, меткой.

person Wayne Hartman    schedule 20.02.2010
comment
Очень интересная идея! Но я полагаю, что я бы изложил свою собственную точку зрения таким образом, правильно? Я могу получить DataGridView или набор элементов управления TextBox примерно за три секунды, перетащив DataSource на форму. Наверное, не так просто сделать набор этикеток? - person John; 21.02.2010
comment
@John из CashCommons - 1) вы можете свернуть свой собственный или 2) вы можете использовать DataGridView и отключить редактирование. 3) Вы можете создать коллекцию элементов управления Label так же просто, как и коллекцию элементов управления TextBox. Помните, что текстовые поля и метки наследуют общий родительский объект Control. - person Wayne Hartman; 21.02.2010
comment
У меня сейчас нет VS 2005, но могу ли я изменить возможность перетаскивания, которую IDE предоставляет для DGV и текстовых полей, чтобы вместо этого давать мне метки? Это, вероятно, был бы лучший путь, которым я мог бы пойти, но если мне придется немного засучить рукава, чтобы добраться туда, я думаю, это не убьет меня, чтобы узнать что-то новое. :) - person John; 21.02.2010

Вместо создания ReadOnlyCollection вы можете изменить свойство в своем классе (MyObjects) на ReadOnly или добавить атрибут System.ComponentModel.ReadOnly(true) к вашему свойству, например:

class Person
{
    public Person(int id, string name, string address)
    {
        _id = id;
        Name = name;
        Address = address;
    }

    private int _id = 0;
    public int ID { get { return _id; } }

    [System.ComponentModel.ReadOnly(true)]
    public string Name { get; set; }

    public string Address { get; set; }
}

ID и Name будут доступны только для чтения, извините, если пример на C#. Надеюсь это поможет.

Ваше здоровье.

person dkartopr    schedule 16.02.2010
comment
Большое спасибо за ответ dkartopr. Вынуждает ли это все экземпляры Person быть доступными только для чтения? В общем, мне понадобится возможность читать и записывать эти объекты. - person John; 17.02.2010
comment
используя System.ComponentModel.ReadOnly(true), да, это будет применяться ко всем экземплярам Person. Скажем, например, у вас есть 1 текстовое поле, которое привязано к свойству Name, изменения, внесенные в текстовое поле, не будут отражены в текущем экземпляре Person. С другой стороны, если вы сделаете: instance.Name = foo, это изменит имя экземпляра на foo. - person dkartopr; 17.02.2010
comment
О, так я могу изменять экземпляры Person только для чтения программно? Я предполагал, что смогу их сконструировать, но тогда значения были высечены в камне (во многом как константный член C++). (Примечание: я думаю, это имело бы смысл, поскольку ваш класс определяет как get, так и set.) - person John; 17.02.2010