絞り込まれたソリューション私ははるかに近づいていますが、XAML を適用してdatacontext値を変更する方法がわかりません。必要に応じて、以下の元の質問のコンテキストを確認してください。
私の問題は、ウィンドウへのデータコンテキストとして ViewModel クラスがあることです。このビュー モデルには、"DataTable" オブジェクトがあります (列とテスト用の 1 行のみ)。テキストボックスの「TEXT」バインディングをデータテーブルの列に設定しようとすると、機能しません。私が最終的に見つけたのは、どのような「ソース」または「パス」を指定しても、それはうまく機能しないということです。ただし、シナリオをいじるだけで、私はそれで言った. 見てみよう。Textbox コントロールには、独自の「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 = ビュー モデルに存在する DataTable) CurrentWindow.DDT.oPerson
私はバインディングで何かに引っかかっています。データテーブルの列をテキスト ボックス コントロールにバインドしたいと考えています。簡単に聞こえますが、何かが欠けています。まずは簡単なシナリオ。ウィンドウがあり、データ コンテキストを "MyDataTable" に設定し、テキスト ボックス PATH=MyDataColumn を持っている場合、データ検証 (エラーの赤い境界線) を含め、すべて問題なく動作します。
さて、問題です。これが私のウィンドウクラスのパブリックと同じ「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 }" />
ウィンドウに公開されているため、「DDT」のソースを含めます
<TextBox Name="myTextBox"
Width="120"
Text="{Binding Source=DDT, Path=Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
そして、grantnz が提供する提案も