2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

WPFでMVVMでDB照会してDataGridに表示する

Posted at

#概要
・MVVMモデルで簡単なDB照会を実装する。
・照会→DB更新→再照会で更新されるのを目標。
・DBはpostgresql。

##開発環境
・開発環境はVisualStudio

##詳細
ソース一覧

フォルダ ファイル 概要
Commands SearchDataBtnCommand.cs DB照会時の処理を記述
ViewModel DBTestPageViewModel.cs DB照会ページのビューモデル
Views DBTestPage.xaml DB照会のページ
Utils DBCommon.cs DB照会用クラス
SearchDataBtnCommand.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Navigation;

namespace LoginProject
{
    /// <summary>
    /// 照会ボタンのコマンド
    /// </summary>
    public class SearchDataBtnCommand : ICommand
    {
        /// <summary>
        /// コマンドを読み出す側のクラス(View Model)を保持するプロパティ
        /// </summary>
        private DBTestPageViewModel _view { get; set; }

        /// <summary>
        /// コンストラクタ
        ///  対応するViewModelを引数に設定しておく
        /// </summary>
        /// <param name="view"></param>
        public SearchDataBtnCommand(DBTestPageViewModel view)
        {
            _view = view;
        }

        /// <summary>
        /// 必ず実装しておくメソッド
        /// </summary>
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        /// <summary>
        /// 必ず実装しておくメソッド
        /// /// コマンドの有効/無効を判定するメソッド
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(object parameter)
        {
            return true;
        }

        /// <summary>
        /// 必ず実装しておくメソッド
        /// コマンドの動作を定義するメソッド
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(object parameter)
        {
            DBCommon db = new DBCommon();
            DataTable DbRet = db.searchAllTrnStock();
            ObservableCollection<DBTestPageViewModel.ViewData> data = new ObservableCollection<DBTestPageViewModel.ViewData>();
            foreach (DataRow dr in DbRet.Rows)
            {
                data.Add(new DBTestPageViewModel.ViewData() { 
                    商品番号 = dr["item_cd"].ToString()
                    ,商品名 = dr["item_name"].ToString()
                    ,在庫数 = dr["stock_num"].ToString()
                    ,作成日 = dr["create_date"].ToString()
                    ,更新日 = dr["update_date"].ToString()
                });   
            }
            _view.DataView = data;

    }
    }

}

DBTestPageViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace LoginProject
{
    /// <summary>
    /// DB照会画面のViewModelクラス
    /// </summary>
    public class DBTestPageViewModel : INotifyPropertyChanged
    {

        // とにかくVIewModelに実装するもの
        public event PropertyChangedEventHandler PropertyChanged;

        // コマンド格納プロパティ
        public SearchDataBtnCommand SearchDataBtnCommand { get; private set; } 

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public DBTestPageViewModel()
        {
            // コマンドインスタンスの生成
            SearchDataBtnCommand = new SearchDataBtnCommand(this);
        }

        private ObservableCollection<ViewData> _dataView = new ObservableCollection<ViewData>();
        public ObservableCollection<ViewData> DataView
        {
            get { return _dataView; }
            set { _dataView = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("DataView"));
                }
            }
        }

        public class ViewData
        {
            public string 商品番号 { get; set; }
            public string 商品名 { get; set; }
            public string 在庫数 { get; set; }
            public string 作成日 { get; set; }
            public string 更新日 { get; set; }
        }

    }
}
DBTestPage.xaml
<Page x:Class="LoginProject.DBTestPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:LoginProject"
      mc:Ignorable="d" 
      d:DesignHeight="450" d:DesignWidth="800"
      Title="DBTestPage">
    <Page.DataContext>
        <local:DBTestPageViewModel/>
    </Page.DataContext>
    <Grid Background="#FF27C22E">
        <Label Content="DBテスト画面" HorizontalAlignment="Left" Margin="278,49,0,0" VerticalAlignment="Top" Height="97" Width="218" FontSize="36" RenderTransformOrigin="0.5,0.5">
            <Label.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform AngleY="0.491"/>
                    <RotateTransform/>
                    <TranslateTransform Y="0.715"/>
                </TransformGroup>
            </Label.RenderTransform>
        </Label>
        <Button Content="照会"  Command="{Binding SearchDataBtnCommand}" HorizontalAlignment="Left" Margin="99,123,0,0" VerticalAlignment="Top" Height="50" Width="121" FontSize="24"/>
        <Button Content="ログアウト" Command="{Binding LogoutBtnCommand}" HorizontalAlignment="Left" Margin="616,40,0,0" VerticalAlignment="Top" Height="50" Width="121" FontSize="24"/>
        <DataGrid ItemsSource="{Binding DataView}" Margin="160,225,185,59" AutoGenerateColumns="True" IsReadOnly="True" CanUserAddRows="false" CanUserDeleteRows="False"  CanUserSortColumns="False"/>

    </Grid>
</Page>

DBCommon.cs
using log4net;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace LoginProject
{
    class DBCommon
    {

        // DB接続文字列
        private String DBConnectStr;
        private ILog log;

        // コンストラクタ
        public DBCommon()
        {
            // ログ準備
            log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().Name);

            // DB接続準備
            var DBConfig = (DBConfigHandler)ConfigurationManager.GetSection("DBConfig");
            DBConnectStr = String.Format("Server={0};Port={1};User ID={2};Database={3};Password={4};Enlist={5}"
                , DBConfig.Connect.Address
                , DBConfig.Connect.Port
                , DBConfig.Connect.UserId
                , DBConfig.Connect.Database
                , DBConfig.Connect.Password
                , DBConfig.Connect.Enlist);
        }

        // 在庫テーブル全検索
        public DataTable searchAllTrnStock()
        {
            var SQL = "SELECT item_cd, item_name, stock_num, create_date, update_date FROM works.trn_stock order by item_cd; ";

            //SQL処理で用いる変数を予め宣言
            NpgsqlCommand cmd = null;
            DataTable dt = null;
            NpgsqlDataAdapter da = null;

            //TransactionScopeの利用
            using (TransactionScope ts = new TransactionScope())
            {
                //接続その1
                using (NpgsqlConnection conn = new NpgsqlConnection(DBConnectStr))
                {
                    conn.Open();

                    //SELECT処理
                    dt = new DataTable();
                    cmd = new NpgsqlCommand(SQL, conn);
                    da = new NpgsqlDataAdapter(cmd);
                    da.Fill(dt);

                }
                //トランザクション完了
                ts.Complete();
            }
            return dt;
        }
    }
}

##動作確認

・DB状態
image.png

・DB照会画面(初期)
image.png

・DB照会画面(照会ボタン押下後)
image.png

・DB更新
image.png

・DB照会画面(再度照会)
image.png

##感想

・思ったよりシンプルに書けたので満足。
・表示するカラムが固定ならこれでOKだけど、可変だったりすると別の方法が必要な気がする。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?