сужен РЕШЕНИЕ
Я гораздо ближе, но не знает, как применить XAML для изменения DataContext значения. Пожалуйста, ознакомьтесь с контекстом первоначального вопроса ниже, если это потребуется.WPF Binding DataTable строка столбец в текстовое поле
Моя проблема заключается в том, что у меня есть класс ViewModel как datacontext для окна. В этой модели представления у меня есть объект «DataTable» (с столбцами и только одна строка для тестирования). Когда я пытаюсь привязать текстовое поле «ТЕКСТ» к столбцу данных, оно не работает. То, что я в конечном итоге нашел, - это то, что независимо от того, какой «источник» или «путь» я ему даю, он просто не будет сотрудничать. ОДНАКО, просто играя со сценариями, я сказал, черт возьми. Давайте посмотрим. Элемент управления Textbox имеет собственное свойство DataContext. Таким образом, в коде я просто FORCED textbox.DataContext = «MyViewModel.MyDataTableObject» и оставил путь только к столбцу, который должен представлять «MyDataColumn», и он сработал.
Итак, как бы я написал XAML для элемента управления текстовым полем, поэтому его свойство «DataContext» установлено на свойство объектного объекта модели представления, но не может получить это правильно. Пример:
<TextBox Name="myTextBox"
Width="120"
DataContext="THIS IS WHAT I NEED" --- to represent
Text="{Binding Path=DataName,
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
DataContext для этого текстового поля должны отражать детали XAML ниже и получить
(ActualWindow) (DDT = View Model) (oPerson = DataTable, которая существует на модели представления) CurrentWindow.DDT.oPerson
Я застрял на что-то с обязательным. Я хочу привязать столбец данных к элементу управления текстовым полем. Звучит просто, но я чего-то не хватает. Сначала простейший сценарий. Если у меня есть мое окно и задано контекст данных для «MyDataTable», и у меня есть текстовое поле PATH = MyDataColumn, все работает нормально, никаких проблем, включая проверку данных (красная граница ошибок).
Теперь проблема. Если у меня есть тот же самый «MyDataTable» как публичный в моем Window Class напрямую (но то же самое, если бы я имел его на фактическом объекте ViewModel, но в окне, чтобы упростить ссылку на уровень), я не могу заставить его работать с прямой источник XAML. Я знал, что мне нужно установить «SOURCE = MyDataTable», но путь только к столбцу не работает.
<TextBox Name="myTextBox"
Text="{Binding Source=DDT, Path=Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
Однако из других испытаний, если я установить путь (в коде-за), чтобы
object txt = FindName("myTextBox");
Binding oBind = new Binding("DataName");
oBind.Source = DDT;
oBind.Mode = BindingMode.TwoWay;
oBind.ValidatesOnDataErrors = true;
oBind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
((TextBox)txt).SetBinding(TextBox.TextProperty, oBind);
он работает (когда DataTable доступен как общественности в окне (или вид модели))
Что мне не хватает в противном случае.
ОБНОВЛЕНИЕ: ЗДЕСЬ ПОЛНАЯ ПОЧТА кода образца, который я подаю здесь.
using System.ComponentModel;
using System.Data;
namespace WPFSample1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public DerivedDataTable DDT;
public MainWindow()
{
InitializeComponent();
// hook up to a Data Table
DDT = new DerivedDataTable();
DataContext = this;
// with THIS part enabled, the binding works.
// DISABLE this IF test, and binding does NOT.
// but also note, I tried these same settings manually via XAML.
object txt = FindName("myTextBox");
if(txt is TextBox)
{
Binding oBind = new Binding("DataName");
oBind.Source = DDT;
oBind.Mode = BindingMode.TwoWay;
oBind.ValidatesOnDataErrors = true;
oBind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
((TextBox)txt).SetBinding(TextBox.TextProperty, oBind);
}
}
}
// Generic class with hooks to enable error trapping at the data table
// level via ColumnChanged event vs IDataErrorInfo of individual properties
public class MyDataTable : DataTable
{
public MyDataTable()
{
// hook to column changing
ColumnChanged += MyDataColumnChanged;
}
protected void MyDataColumnChanged(object sender, DataColumnChangeEventArgs e)
{ ValidationTest(e.Row, e.Column.ColumnName); }
// For any derived datatable to just need to define the validation method
protected virtual string ValidationTest(DataRow oDR, string ColumnName)
{ return ""; }
}
public class DerivedDataTable : MyDataTable
{
public DerivedDataTable()
{
// simple data table, one column, one row and defaulting the value to "X"
// so when the window starts, I KNOW its properly bound when the form shows
// "X" initial value when form starts
Columns.Add(new DataColumn("DataName", typeof(System.String)) );
Columns["DataName"].DefaultValue = "X";
// Add a new row to the table
Rows.Add(NewRow());
}
protected override string ValidationTest(DataRow oDR, string ColumnName)
{
string error = "";
switch (ColumnName.ToLower())
{
case "dataname" :
if ( string.IsNullOrEmpty(oDR[ColumnName].ToString())
|| oDR[ColumnName].ToString().Length < 4)
error = "Name Minimum 4 characters";
break;
}
// the datarow "SetColumnError" is what hooks the "HasErrors" validation
// in similar fashion as IDataErrorInfo.
oDR.SetColumnError(Columns[ColumnName], error);
return error;
}
}
}
И вот XAML. Любая новая форма, и это единственный элемент управления в «сетке» по умолчанию окна.
Пробовал следующие версии, просто определение строки [0] [Колонка]
<TextBox Name="myTextBox"
Width="120"
Text="{Binding Path=Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
В том числе источник «ДДТ», поскольку она является общедоступной к окну
<TextBox Name="myTextBox"
Width="120"
Text="{Binding Source=DDT, Path=Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
И даже предложения, предлагаемые by grantnz
Grantnz, нет, я не получаю сообщение об ошибке на кайфа. Я попробовал ваш Path = DDT.Rows [0] [DataName], и это было неудачно. Я попытался включить RelativeSource/FindAncestor тоже, не работал. Спасибо за предложения. – DRapp
@DRapp - Вы устанавливаете DDT до или после настройки привязки? Если вы устанавливаете его из кода в конструкторе окна, попробуйте переместить код выше InitializeComponent(); (или реализовать INotifyPropertyChanged). – grantnz
@DRapp - Я удивлен, что вы не видите никаких ошибок привязки в окне вывода. Что произойдет, если вы сделаете преднамеренную ошибку (например, Path = PropertyThatDoesntExist)? – grantnz