缩小的解决方案
我更接近,但不知道如何应用 XAML 来更改 datacontext 值。请根据需要查看下面原始问题的上下文。
我的问题是我有一个 ViewModel 类作为窗口的数据上下文。在这个视图模型上,我有一个“DataTable”对象(带有列和只有一行用于测试)。当我尝试将文本框“TEXT”绑定设置到数据表的列时,它不起作用。我最终发现的是,无论我给它什么“来源”或“路径”,它都不会合作。然而,只是通过玩一些场景,我说得对。我们看看吧。文本框控件有自己的“DataContext”属性。因此,在代码中,我只是强制 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 = 视图模型) (oPerson = 存在于视图模型上的数据表) CurrentWindow.DDT.oPerson
我被困在有约束力的东西上。我想将数据表的一列绑定到文本框控件。听起来很简单,但我错过了一些东西。先说简单的场景。如果我有我的窗口并将数据上下文设置为“MyDataTable”,并且有文本框 PATH=MyDataColumn,那么一切正常,没有问题,包括数据验证(红色边框错误)。
现在,问题。如果我直接在我的 Window 类上有一个与 public 相同的“MyDataTable”(但如果我在一个实际的 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);
它确实有效(当数据表在窗口(或视图模型)中作为公共可用时)
否则我错过了什么。
更新:这是我在此处应用的示例代码的完整帖子。
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。任何全新的窗体,这是窗口默认“网格”中的唯一控件。
尝试了以下版本,只定义了 Rows[0][Column]
<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 }" />
甚至grantnz提供的建议