実行時に SQL クエリを記述して、WPF Datagrid に SQL テーブルを表示したいと考えています。View (簡略化) と ViewModel を関連付けて作成しました。
意見:
-----------------MyDataGrid.xaml-----------------
<DataGrid x:Name="CurrentSqlGrid"
ItemsSource="{Binding Path=CurrentDataTable,Mode=OneWay}"
Grid.Row="2" AutoGenerateColumns="True" IsReadOnly="True" />
<TextBox x:Name="TextBoxSql" Height="120" Grid.Row="1"
TextWrapping="Wrap" VerticalAlignment="Top"/>
-----------------MyDataGrid.cs-----------------
public partial class MyDataGrid : UserControl
{
private SqlDataGridViewModel sqlDataGridViewModel;
public MyDataGrid()
{
InitializeComponent();
sqlDataGridViewModel = new SqlDataGridViewModel();
this.DataContext = sqlDataGridViewModel;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
sqlDataGridViewModel.FillDataTableWithQuery(TextBoxSql.Text);
}
}
ビューモデル:
-----------------SqlDataGridViewModel.cs-----------------
public class SqlDataGridViewModel
{
private DataTable _dataTable;
private SqlDataAdapter _adapter;
public DataTable CurrentDataTable
{
get
{
return _dataTable;
}
set
{
_dataTable = value;
}
}
public SqlDataGridViewModel()
{
_dataTable = new DataTable("QUERY");
FillDataTableWithQuery("SELECT TOP 500 * FROM XUSER");
}
public void FillDataTableWithQuery(string query)
{
CurrentDataTable.Reset();
CurrentDataTable.Clear();
try
{
using (SqlConnection sqlConn = new SqlConnection(SessionProvider.Instance.currentConnectionString))
{
_adapter = new SqlDataAdapter(query, sqlConn);
_adapter.Fill(CurrentDataTable);
}
}
catch (Exception ex)
{
MartuLogger.Instance.Error("Exception in SqlDataGridViewModel :" + ex.Message);
}
}
}
このソリューションは、最初のクエリの最初の DataTable を表示します。
しかし、別の SQL クエリを作成するとFillDataTableWithQuery("SELECT * from another_table")
、Datagrid を呼び出すとすべての行がクリアされますが、新しい列と新しい行は読み込まれません! (古い列のみを表示します!)。デバッグでは、CurrentDataTable
新しいクエリの結果が含まれています....何かアイデアはありますか?
解決 策 Faisal Hafeez の助けを借りて、次の解決策を見つけました。
Xaml と分離コードは同じです。OneWay および TwoWay モードで動作します。
私のビューモデルは次のようになります:
public class SqlDataGridViewModel : INotifyPropertyChanged
{
private DataTable _dataTable;
private SqlDataAdapter _adapter;
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChange(string PropertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
public DataTable CurrentDataTable
{
get
{
return _dataTable;
}
set
{
_dataTable = value;
//NotifyPropertyChange("CurrentDataTable");
}
}
public SqlDataGridViewModel()
{
_dataTable = new DataTable("QUERY");
FillDataTableWithQuery("SELECT TOP 500 * FROM XUSER");
}
public void FillDataTableWithQuery(string query)
{
_dataTable = new DataTable("QUERY");
try
{
using (SqlConnection sqlConn = new SqlConnection(SessionProvider.Instance.currentConnectionString))
{
_adapter = new SqlDataAdapter(query, sqlConn);
_adapter.Fill(CurrentDataTable);
}
NotifyPropertyChange("CurrentDataTable");
}
catch (Exception ex)
{
MartuLogger.Instance.Error("Exception in SqlDataGridViewModel :" + ex.Message);
}
}
}
_adapter.Fill の後に NotifyPropertyChange を行わないと、ビューが更新されません。(私は Set CurrentTable で通知しようとしましたが、_adapter.Fill は明らかに CurrentTable の set メソッドを呼び出しません)。ありがとうございました。