#c# #winforms #data-binding
#c# #winforms #привязка к данным
Вопрос:
Среда: Visual Studio 2010, .NET 4.0, WinForms
У меня есть DataSet
который реализует INotifyPropertyChanged
, и я создал bool
свойство для DataSet
. Я пытаюсь привязать CheckBox.Checked
свойство к этому bool
свойству. Когда я пытаюсь сделать это в конструкторе, я вижу DataSet
и таблицы в DataSet
, но не свойство. Я попытался сделать это вручную, но получил сообщение об ошибке, что свойство не найдено. Единственное отличие, которое я вижу в том, что я делаю, это то, что свойство в форме является суперклассом DataSet
, экземпляр которого создается, но я даже не вижу, как это на что-либо повлияет. Фрагмент кода приведен ниже.
Определение производного класса
public class DerivedDataSetClass: SuperDataSetClass, INotifyPropertyChanged
{
private bool _mainFile = false;
public bool MainFile
{
get { return this._mainFile; }
set {
this._mainFile = value;
this.NotifyPropertyChanged("MainFile");
}
}
}
Определение свойства
private SuperDataSetClass _dataSet;
public DerivedDataSetClass DataSet
{
get { return (DerivedDataSetClass)_dataSet;
}
Ctor
this._DataSet = new DerivedDataSetClass (this);
this.mainFileBindingSource = new BindingSource();
this.mainFileBindingSource.DataSource = typeof(DerivedDataSetClass);
this.mainFileBindingSource.DataMember = "MainFile";
var binding = new Binding("Checked", this.mainFileBindingSource, "MainFile");
this.chkMainFile.DataBindings.Add(binding);
Мысли?
Ответ №1:
Проблемы напрямую связаны с тем, как вы хотите использовать свой DerivedDataSetClass
. Поскольку это так DataSet
, любая выполняемая привязка будет использовать значение по умолчанию DataViewManager
, которое «подталкивает» привязку к Tables
привязке.
Когда вы привязываетесь к своему DerivedDataSet
MainFile
свойству, то, что делается под капотом, является попыткой привязки к таблице, названной MainFile
в таблицах вашего набора данных. Конечно, это не удается, если у вас действительно нет такой таблицы в dataset. По той же причине вы не можете выполнить привязку к любому другому свойству base DataSet
— например. Locale
или HasErrors
— также проверяется, существуют ли такие таблицы, а не свойства.
Каковы решения этой проблемы? Вы можете попробовать реализовать другое DataViewManager
— однако я не смог найти надежных ресурсов по этой теме.
Что я предлагаю, так это создать простой класс-оболочку для вашего MainFile
свойства и связанного с ним DerivedDataSetClass
, например:
public class DerivedDataSetWrapper : INotifyPropertyChanged
{
private bool _mainFile;
public DerivedDataSetWrapper(DerivedDataSetClass dataSet)
{
this.DataSet = dataSet;
}
// I assume no notification will be needed upon DataSet change;
// hence auto-property here
public DerivedDataSetClass DataSet { get; private set; }
public bool MainFile
{
get { return this._mainFile; }
set
{
this._mainFile = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("MainFile"));
}
}
}
Теперь вы можете привязываться как к внутреннему содержимому dataset (таблицам), так и MainFile
к вашему классу-оболочке.
var wrapper = new DerivedDataSetWrapper(this._DataSet);
BindingSource source = new BindingSource { DataSource = wrapper };
// to bind to checkbox we essentially bind to Wrapper.MainFile
checkBox.DataBindings.Add("Checked", source, "MainFile", false,
DataSourceUpdateMode.OnPropertyChanged);
Чтобы привязать данные из таблиц в dataset, вам нужно привязать к DerivedDataSetWrapper
DataSet
свойству, а затем перемещаться по именам таблиц и столбцам. Например:
textBox.DataBindings.Add("Text", source, "DataSet.Items.Name");
… будет привязываться к таблице Items
и столбцу Name
в вашем оригинале _DataSet
.
Комментарии:
1. К сожалению, это не помогло. Когда форма пытается отобразить, я получаю исключение invalidargument, к которому не удалось привязать свойство MainFile в методе CheckBindings системы. Формы.
2. @wraith808: Да, я воспроизвел вашу проблему. Это связано с тем, как выполняется
DataSet
привязка — проверьте мою правку.3. Спасибо за информацию! Я пытался обойти это с помощью метода щелчка флажком, но, учитывая накладные расходы и тот факт, что это существующее приложение, я думаю, что это чище. Но я рад узнать причину, обходной путь и то, что я не сумасшедший из-за того, что я увидел. 😉