3

実行時に 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 メソッドを呼び出しません)。ありがとうございました。

4

1 に答える 1

1

これを試して。データグリッドの設定イベントで INotifyPropertyChanged を実装し、PropertyChanged を呼び出す必要があります。

public class SqlDataGridViewModel : INotifyPropertyChanged {

public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(String info)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}

public DataTable CurrentDataTable
    {
        get
        {
            return _dataTable;
        }
        set
        {
            _dataTable = value;
            OnPropertyChanged("CurrentDataTable");
        }
    }
}
于 2013-04-15T14:34:31.133 に答える