Hatena::ブログ(Diary)

kabahandleのC#日記

2013-10-06

コンテキストメニューをインターフェースに合わせて切り替え表示

| 16:54

MyDummySQLProに、ショートカットメニューをつけてみました。

f:id:kabacsharp:20131006164055p:image

主に、テキストボックスに入っているスクリプトテンプレートに保存するためのメニュー項目をつけたかったからです。

AccessSavableTextBoxは継承させたかったので、またまたインターフェースでクラス(オブジェクト)を識別認識させています。


IHasCategorizedTextAndContextMenuインターフェースを実装したテキストボックス:TextBoxForTemplate

namespace MyDummySQL.ControlsForTemplate
{
    public class TextBoxForTemplate : AccessSavableTextBox, IHasCategorizedTextAndContextMenu
    {
        private string categoryName = "dummy";
        public string CategoryName {
            get
            {
                if (this.Parent != null && "dummy".Equals(this.categoryName))
                {
                    return this.Parent.Text;
                }
                return this.categoryName;
            }
            set
            {
                this.categoryName = value;
            }
        }

        public TextBoxForTemplate()
            : base()
        {
            this.ContextMenuStrip = (new ContextMenuBuilderFactory()).Create(this).Build();
        }
        public TextBoxForTemplate(string categoryName) : base()
        {
            this.categoryName = categoryName;
            this.ContextMenuStrip = (new ContextMenuBuilderFactory()).Create(this).Build();
        }


    }
}

今回インターフェイスは2種あります。

一つ目、ふつうの「コピー」「切り取り」「貼り付け」しかないコンテキストメニューを表示させるテキストボックス用:IHasTextAndContextMenu

namespace MyDummySQL.ControlsForTemplate
{
    public interface IHasTextAndContextMenu
    {
        string Text { get; set; }
        string SelectedText { get; set; }
        //System.Windows.Forms.ContextMenuStrip ContextMenuStrip { get; set; }
    }
}

二つ目、一つ目のメニューに加えて「テンプレートに保存」「テンプレートから取得」のメニュー項目も表示するテキストボックス用:

namespace MyDummySQL.ControlsForTemplate
{
    public interface IHasCategorizedTextAndContextMenu : IHasTextAndContextMenu
    {
        string CategoryName { get; set; }
    }
}

次に、メニューを作成するクラスを、インターフェースで切り替え生成するファクトリ:ContextMenuBuilderFactory

namespace MyDummySQL.ControlsForTemplate
{
    public class ContextMenuBuilderFactory
    {
        public ContextMenuBuilderFactory() { }

        public ContextMenuBuilder Create(IHasTextAndContextMenu control)
        {
            return new ContextMenuBuilder(control);
        }

        public ContextMenuBuilder Create(IHasCategorizedTextAndContextMenu control)
        {
            return new ContextMenuBuilderWidthCategory(control);
        }
    }
}

次に実際に普通のメニューを作成する”自称ビルダー”(注:ビルダーパターンではないです):ContextMenuBuilder

namespace MyDummySQL.ControlsForTemplate
{
    public class ContextMenuBuilder
    {
        //ContextMenu 
        protected ContextMenuStrip cMenu = new ContextMenuStrip();

        protected IHasTextAndContextMenu HasText = null;

        public ContextMenuBuilder(IHasTextAndContextMenu control)
        {
            this.HasText = control;
        }

        virtual public ContextMenuStrip Build()
        {
            //this.HasText = control;
            /*
            this.BuildCopy();
            this.BuildCut();
            this.BuildPaste();
             */
            this.BuildBasicMenu();
            return this.cMenu;
        }

        private void BuildBasicMenu()
        {
            this.BuildCopy();
            this.BuildCut();
            this.BuildPaste();
        }

        virtual protected void BuildCopy()
        {
            //Copy
            ToolStripMenuItem mCopy = new ToolStripMenuItem();
            mCopy.Text = "コピー(&C)";
            mCopy.Click += delegate
            {
                if (!string.IsNullOrEmpty(this.HasText.SelectedText))
                {
                    Clipboard.SetText(this.HasText.SelectedText);
                }
                else if (!string.IsNullOrEmpty(this.HasText.Text))
                {
                    Clipboard.SetText(this.HasText.Text);
                }
            };
            this.cMenu.Items.Add(mCopy);
        }

        virtual protected void BuildCut()
        {
            //Cut
            ToolStripMenuItem mCut = new ToolStripMenuItem();
            mCut.Text = "切り取り(&X)";
            mCut.Click += delegate
            {
                if (!string.IsNullOrEmpty(this.HasText.SelectedText))
                {
                    Clipboard.SetText(this.HasText.SelectedText);
                    this.HasText.SelectedText = "";
                }
                else if (!string.IsNullOrEmpty(this.HasText.Text))
                {
                    Clipboard.SetText(this.HasText.Text);
                    this.HasText.Text = "";
                }
            };
            this.cMenu.Items.Add(mCut);
        }

        virtual protected void BuildPaste()
        {
            //Paste
            ToolStripMenuItem mPaste = new ToolStripMenuItem();
            mPaste.Text = "貼り付け(&V)";
            mPaste.Click += delegate
            {
                if (!string.IsNullOrEmpty(this.HasText.SelectedText))
                {
                    this.HasText.SelectedText = Clipboard.GetText();
                }
                else
                {
                    this.HasText.Text = Clipboard.GetText();
                }
            };
            cMenu.Items.Add(mPaste);
        }

    }
}

さらに上のクラスを継承して、「テンプレートに保存」「テンプレートから取得」メニューを追加する”自称ビルダー”:ContextMenuBuilder

(ただし、テンプレート保存・取得の実装プログラムはまだ作っていませんので、仮です)

namespace MyDummySQL.ControlsForTemplate
{
    public class ContextMenuBuilderWidthCategory : ContextMenuBuilder
    {
        //private IHasCategorizedTextAndContextMenu HasCategorizedText = null;

        public ContextMenuBuilderWidthCategory(IHasCategorizedTextAndContextMenu control)
            : base(control)
        {
            this.HasText = control;
        }

        public override ContextMenuStrip Build()
        {
            this.cMenu = base.Build();
            BuildAddToTemplate();
            BuildGetFromTemplate();

            return this.cMenu;
        }

        virtual public void BuildAddToTemplate()
        {
            //Copy
            ToolStripMenuItem mToTemp = new ToolStripMenuItem();
            mToTemp.Text = "テンプレートに保存(&T)";
            mToTemp.Click += delegate
            {
                string template = string.Empty;
                string category = string.Empty;

                if (!string.IsNullOrEmpty(this.HasText.SelectedText))
                {
                    template = this.HasText.SelectedText;
                }
                else if (!string.IsNullOrEmpty(this.HasText.Text))
                {
                    template = this.HasText.Text;
                }

                IHasCategorizedTextAndContextMenu obj = this.HasText as IHasCategorizedTextAndContextMenu;
                if (obj != null)
                {
                    category = obj.CategoryName;
                }

                frmAddTemplates addFrm = new frmAddTemplates(category, template);
                addFrm.Show();

            };
            this.cMenu.Items.Add(mToTemp);
        }
        virtual public void BuildGetFromTemplate()
        {
            //Copy
            ToolStripMenuItem mFromTemp = new ToolStripMenuItem();
            mFromTemp.Text = "テンプレートから取得(&G)";
            mFromTemp.Click += delegate
            {
                string template = string.Empty;
                string category = string.Empty;

                if (!string.IsNullOrEmpty(this.HasText.SelectedText))
                {
                    template = this.HasText.SelectedText;
                }
                else if (!string.IsNullOrEmpty(this.HasText.Text))
                {
                    template = this.HasText.Text;
                }

                IHasCategorizedTextAndContextMenu obj = this.HasText as IHasCategorizedTextAndContextMenu;
                if (obj != null)
                {
                    category = obj.CategoryName;
                }

                frmTemplates frmTemp = new frmTemplates();
                frmTemp.Show();

            };
            this.cMenu.Items.Add(mFromTemp);
        }

    }
}

テンプレート関連を扱うフォームは以下のような感じです。

f:id:kabacsharp:20131006165222p:image

f:id:kabacsharp:20131006165332p:image

・・・つ、疲れた。また来週〜。

トラックバック - http://d.hatena.ne.jp/kabacsharp/20131006

2013-10-05 Accessにシリアライズ可能なTextBox, ComboBox, ListBox

Accessにシリアライズ可能なTextBox, ComboBox, ListBox

| 16:49

シリアライズというと、XMLのような気もしますが、

VB6からAccessに慣れ親しんだおいらには、Accessに設定保存してみたいと思えます。

そこで!作ってみました。

まずは、アクセス保存可能インターフェース:IAccessSavable

namespace MyDummySQL.AccessSavables
{
    interface IAccessSavable
    {
        string Ext { get; set; }
        void Save(DAOContext con, string header);
        void Load(DAOContext con, string header);
        void SetExt(string ext_);
    }
}

インターフェース継承したTextBox:AccessSavableTextBox

namespace MyDummySQL.AccessSavables
{
    public class AccessSavableTextBox : TextBox, IAccessSavable
    {
        public string Ext { get; set; }

        public AccessSavableTextBox() : base() 
        {
            this.Ext = "ext";
        }

        public void Save(DAOContext con, string header)
        {
            string saveText = this.Text;
            if (char.IsLetter(this.PasswordChar) )
            {
                //暗号化
                saveText = CryptHelper.EncryptString(saveText, CryptHelper.cryptseed);
            }

            MyDummySQLSettingsSingleton.setValue(con, header, "KEY_" + this.Ext.ToUpper() + "_" + this.Name.ToUpper(), this.Text);
        }
        public void Load(DAOContext con, string header)
        {
            string loadText = MyDummySQLSettingsSingleton.getStringValue(con, header, "KEY_" + this.Ext.ToUpper() + "_"  + this.Name.ToUpper());

            if (char.IsLetter(this.PasswordChar) )
            {
                //暗号化
                loadText = CryptHelper.DecryptString(loadText, CryptHelper.cryptseed);
            }

            this.Text = loadText;

        }
        public void SetExt(string ext_)
        {
            this.Ext = ext_;
        }
    }
}

インターフェース継承したComboBox: AccessSavableComboBox

namespace MyDummySQL.AccessSavables
{
    public class AccessSavableComboBox : ComboBox, IAccessSavable
    {
        public string Ext { get; set; }

        public AccessSavableComboBox()
            : base()
        {
            this.Ext = "ext";
        }

        public void Save(DAOContext con, string header)
        {
            string key = "KEY_" + this.Ext.ToUpper() + "_" + this.Name.ToUpper();
            string idxkey = "KEY_" + this.Ext.ToUpper() + "_IDX_" + this.Name.ToUpper();
            
            int idx = this.SelectedIndex;

            //delete
            MyDummySQLSettingsSingleton.deleteSettings(con, header, key);
            MyDummySQLSettingsSingleton.deleteSettings(con, header, idxkey);

            //set
            List<string> strs = new List<string>();

            foreach (object o in this.Items)
            {
                strs.Add(o.ToString());
            }
            MyDummySQLSettingsSingleton.setStringValues(con, header, key, strs);

            //save idx
            MyDummySQLSettingsSingleton.setValue(con, header, key, idx);
        }

        public void Load(DAOContext con, string header)
        {
            this.Items.Clear();
            string key = "KEY_" + this.Ext.ToUpper() + "_" + this.Name.ToUpper();
            string idxkey = "KEY_" + this.Ext.ToUpper() + "_IDX_" + this.Name.ToUpper();

            //load
            this.Items.AddRange(MyDummySQLSettingsSingleton.getStringValues(con, header, key).ToArray());

            //load idx
            int idx = 0;
            MyDummySQLSettingsSingleton.getValue(con, header, key, out idx);
            if (this.Items.Count > idx)
            {
                this.SelectedIndex = idx;
            }

        }

        public void SetExt(string ext_)
        {
            this.Ext = ext_;
        }

    }
}

インターフェース継承したComboBox: AccessSavableListBox

namespace MyDummySQL.AccessSavables
{
    public class AccessSavableListBox : ListBox, IAccessSavable
    {
        public string Ext { get; set; }

        public AccessSavableListBox() : base() 
        {
            this.Ext = "ext";
        }

        public void Save(DAOContext con, string header)
        {
            string key = "KEY_" + this.Ext.ToUpper() + "_" + this.Name.ToUpper();
            string idxkey = "KEY_" + this.Ext.ToUpper() + "_IDX_" + this.Name.ToUpper();

            int idx = this.SelectedIndex;

            //delete
            MyDummySQLSettingsSingleton.deleteSettings(con, header, key);
            MyDummySQLSettingsSingleton.deleteSettings(con, header, idxkey);

            //set
            List<string> strs = new List<string>();
            
            foreach (object o in this.Items)
            {
                strs.Add(o.ToString());
            }
            MyDummySQLSettingsSingleton.setStringValues(con, header, key, strs);

            //save idx
            MyDummySQLSettingsSingleton.setValue(con, header, key, idx);
        }

        public void Load(DAOContext con, string header)
        {
            this.Items.Clear();
            string key = "KEY_" + this.Ext.ToUpper() + "_" + this.Name.ToUpper();
            string idxkey = "KEY_" + this.Ext.ToUpper() + "_IDX_" + this.Name.ToUpper();

            //load
            this.Items.AddRange(MyDummySQLSettingsSingleton.getStringValues(con, header, key).ToArray());

            //load idx
            int idx = 0;
            MyDummySQLSettingsSingleton.getValue(con, header, key, out idx);
            if (this.Items.Count > idx)
            {
                this.SelectedIndex = idx;
            }

        }

        public void SetExt(string ext_)
        {
            this.Ext = ext_;
        }

    }
}

Accessに設定を保存するヘルパーシングルトン:MyDummySQLSettingsSingleton

namespace MyDummySQL.DAOs
{
   public class MyDummySQLSettingsSingleton
    {

        #region //定数
        public static string TRUE = "true";
        public static string FALSE = "false";
        #endregion

        public class values
        {
            public int intValue = 0;
            public string strgValue = "";
            public values(int intvalue, string strgvalue)
            {
                this.intValue = intvalue;
                this.strgValue = strgvalue;
            }
        }

        private static MyDummySQLSettingsSingleton sigleton_ = new MyDummySQLSettingsSingleton();

        MyDummySQLSettingsSingleton()
        {
        }

        public MyDummySQLSettingsSingleton getInstance()
        {
            return MyDummySQLSettingsSingleton.sigleton_;
        }



        public static IList<string> getHeaderTexts()
        {
            List<string> headertexts = new List<string>();
            DataTable tbl = null;
            //DBから読み込む
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                tbl = dao.selectHeaders();

                con.CloseConnection();
            }

            if (tbl != null)
            {
                foreach (DataRow row in tbl.Rows)
                {
                    headertexts.Add(row["HEADERTEXT"].ToString());
                }
            }
            return headertexts;
        }
        public static IList<string> getHeaderTexts(DAOContext con)
        {
            List<string> headertexts = new List<string>();
            DataTable tbl = null;
            //DBから読み込む
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            tbl = dao.selectHeaders();

            if (tbl != null)
            {
                foreach (DataRow row in tbl.Rows)
                {
                    headertexts.Add(row["HEADERTEXT"].ToString());
                }
            }
            return headertexts;
        }

        public static void deleteSettings(string headerText)
        {

            //DBから読み込む
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                dao.deleteSettings(headerText);
                dao.deleteHeader(headerText);

                con.CloseConnection();


            }
        }
        public static void deleteSettings(DAOContext con, string headerText)
        {

            //DBから読み込む
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            dao.deleteSettings(headerText);
            dao.deleteHeader(headerText);

        }
        public static void getValue(string headerText, string strgKey, out int intValue)
        {
            intValue = 0;

            //DBから読み込む
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                dao.selectSetting(headerText, strgKey, out intValue);

                con.CloseConnection();


            }
        }
        public static void getValue(DAOContext con, string headerText, string strgKey, out int intValue)
        {
            intValue = 0;
            if (con.Connection.State != ConnectionState.Open) return;


            //DBから読み込む
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            dao.selectSetting(headerText, strgKey, out intValue);

        }
        public static string getStringValue(string headerText, string strgKey)
        {
            string strgValue = "";

            //DBから読み込む
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                dao.selectSetting(headerText, strgKey, out strgValue);

                con.CloseConnection();

            }
            return strgValue;
        }
        public static string getStringValue(DAOContext con, string headerText, string strgKey)
        {
            string strgValue = "";
            if (con.Connection.State != ConnectionState.Open) return "";

            //DBから読み込む
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            dao.selectSetting(headerText, strgKey, out strgValue);

            return strgValue;
        }
        public static IList<string> getStringValues(string headerText, string strgKey)
        {
            List<string> ret = new List<string>();
            DataTable tbl = null;

            //DBから読み込む
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                tbl = dao.selectSettingRows(headerText, strgKey);

                con.CloseConnection();

            }

            if (tbl != null)
            {
                foreach (DataRow row in tbl.Rows)
                {
                    ret.Add(row["TEXTVALUE"].ToString());
                }
            }

            return ret;
        }
        public static IList<string> getStringValues(DAOContext con, string headerText, string strgKey)
        {
            List<string> ret = new List<string>();
            DataTable tbl = null;

            if (con.Connection.State != ConnectionState.Open) return ret;

            //DBから読み込む
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            tbl = dao.selectSettingRows(headerText, strgKey);

            if (tbl != null)
            {
                foreach (DataRow row in tbl.Rows)
                {
                    ret.Add(row["TEXTVALUE"].ToString());
                }
            }

            return ret;
        }

        public static void setStringValues(string headerText, string strgKey, IList<string> strgs)
        {
            int no = 1;
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

                dao.deleteSettings(headerText, strgKey);

                foreach (string strg in strgs)
                {
                    dao.insertNew(headerText, strgKey, no, strg);
                    no++;
                }

                con.CloseConnection();
            }

        }
        public static void setStringValues(DAOContext con, string headerText, string strgKey, IList<string> strgs)
        {
            if (con.Connection.State != ConnectionState.Open) return;
            int no = 1;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);

            dao.deleteSettings(headerText, strgKey);

            foreach (string strg in strgs)
            {
                dao.insertNew(headerText, strgKey, no, strg);
                no++;
            }
        }

        public static void setValue(string headerText, string strgKey, int intValue)
        {
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
                dao.mergeSettings(headerText, strgKey, intValue);
                con.CloseConnection();
            }

        }
        public static void setValue(DAOContext con, string headerText, string strgKey, int intValue)
        {
            if (con.Connection.State != ConnectionState.Open) return;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
            dao.mergeSettings(headerText, strgKey, intValue);
        }
        public static void setValue(string headerText, string strgKey, string strgValue)
        {
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
                dao.mergeSettings(headerText, strgKey, strgValue);
                con.CloseConnection();
            }
        }
        public static void setValue(DAOContext con, string headerText, string strgKey, string strgValue)
        {
            if (con.Connection.State != ConnectionState.Open) return;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
            dao.mergeSettings(headerText, strgKey, strgValue);
        }

        public static bool isExistsHeader(string headerText)
        {
            bool ret = false;
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
                ret = dao.isExistsHeader(headerText);
                con.CloseConnection();
            }
            return ret;
        }
        public static bool isExistsHeader(DAOContext con, string headerText)
        {
            if (con.Connection.State != ConnectionState.Open) return false;
            bool ret = false;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
            ret = dao.isExistsHeader(headerText);
            return ret;
        }
        public static void MergeHeader(string headerText)
        {
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
                dao.mergeHeader(headerText);
                con.CloseConnection();
            }
        }
        public static void MergeHeader(DAOContext con, string headerText)
        {
            if (con.Connection.State != ConnectionState.Open) return;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
            dao.mergeHeader(headerText);
        }
        public static void deleteSettings(string headerText, string strgKey)
        {
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
                dao.deleteSettings(headerText, strgKey);
                con.CloseConnection();
            }
        }
        public static void deleteSettings(DAOContext con, string headerText, string strgKey)
        {
            if (con.Connection.State != ConnectionState.Open) return;
            MyDummySQLSettingsDAO dao = new MyDummySQLSettingsDAO(con);
            dao.deleteSettings(headerText, strgKey);
        }
    }
}

Accessに設定を保存するDAO:MyDummySQLSettingsDAO

namespace MyDummySQL.DAOs
{
    class MyDummySQLSettingsDAO : MyDAOBase
    {
        public MyDummySQLSettingsDAO(DAOContext con) : base(con) { }

        #region //SELECT
        public void selectSetting(string headerText, string strgKey, out int intValue)
        {
            string sql = @"select *
                            from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            DataTable tbl = base.GetTable(sql);

            if (tbl.Rows.Count > 0)
            {
                int ret = 0;
                int.TryParse(tbl.Rows[0]["INTVALUE"].ToString(), out ret);
                intValue = ret;
            }
            else
            {
                intValue = 0;
            }
        }

        public DataRow selectSetting1Row(string headerText, string strgKey)
        {
            string sql = @"select *
                            from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            DataTable tbl = base.GetTable(sql);

            if (tbl.Rows.Count > 0)
            {
                return tbl.Rows[0];
            }
            else
            {
                return null;
            }
        }
        public DataTable selectSettingRows(string headeText, string strgKey)
        {
            string sql = @"select *
                            from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader
                            order by NO1
                            ";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headeText);

            return  base.GetTable(sql);

        }

        public void selectSetting(string headerText, string strgKey, out string strgValue)
        {
            string sql = @"select *
                            from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            DataTable tbl = base.GetTable(sql);

            if (tbl.Rows.Count > 0)
            {
                strgValue = tbl.Rows[0]["TEXTVALUE"].ToString();
            }
            else
            {
                strgValue = "";
            }
        }
        public DataTable selectHeaders()
        {
            string sql = @"select *
                            from header
                            order by HEADERTEXT
                            ";

            this.ClearParameters();

            return base.GetTable(sql);

        }

        public bool isExistSetting(string headerText, string strgKey)
        {
            string sql = @"select *
                            from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT = @pheader";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            DataTable tbl = base.GetTable(sql);

            if (tbl.Rows.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        #endregion

        #region //ヘッダーマージ

        public bool isExistsHeader(string headerText)
        {
            string sql = @"select * 
                            from header
                            where
                                HEADERTEXT like @pheader
                                ";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);

            DataTable tbl =  base.GetTable(sql);

            if (tbl.Rows.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public int insertNewHeader(string headerText)
        {
            string sql = @"insert into
                            header(
                                HEADERTEXT
                            )
                            values(
                                @pheader
                            )";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }

        public int mergeHeader(string headerText)
        {
            if (this.isExistsHeader(headerText))
            {
                return 0;
            }
            else
            {
                return this.insertNewHeader(headerText);
            }
        }

        #endregion


        #region //数値設定

        public int updateDate(string headerText, string strgKey, int intValue)
        {
            string sql = @"update settings
                            set
                                INTVALUE = @pintvalue
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pintvalue", DbType.Int32, intValue);
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }

        public int insertNew(string headerText, string strgKey, int intValue)
        {
            string sql = @"insert into
                            settings(
                                HEADERTEXT
                                ,NO1
                                ,SETTINGKEY
                                ,INTVALUE
                            )
                            values(
                                @pheader
                                ,0
                                ,@pkey
                                ,@pintvalue
                            )";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pintvalue", DbType.Int32, intValue);

            return base.ExecuteNonQuery(sql);
        }

        public int mergeSettings(string headerText, string strgKey, int intValue)
        {
            if (this.isExistSetting(headerText, strgKey))
            {
                return this.updateDate(headerText, strgKey, intValue);
            }
            else
            {
                return this.insertNew(headerText, strgKey, intValue);
            }
        }

        #endregion


        #region //数値設定(複数行)

        public int insertNew(string headerText, string strgKey, int no, int intValue)
        {
            string sql = @"insert into
                            settings(
                                HEADERTEXT
                                ,NO1
                                ,SETTINGKEY
                                ,INTVALUE
                            )
                            values(
                                @pheader
                                ,@pno
                                ,@pkey
                                ,@pintvalue
                            )";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);
            this.AddParameter("pno", DbType.Int32, no);
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pintvalue", DbType.Int32, intValue);

            return base.ExecuteNonQuery(sql);
        }

        #endregion


        #region //文字設定

        public int updateDate(string headerText, string strgKey, string strgValue)
        {
            string sql = @"update settings
                            set
                                TEXTVALUE = @ptextvalue
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("ptextvalue", DbType.String, strgValue);
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }

        public int insertNew(string headerText, string strgKey, string strgValue)
        {
            string sql = @"
insert into
settings(
HEADERTEXT
,NO1
,SETTINGKEY
,TEXTVALUE
)
values(
@pheader1
,0
,@pkey1
,@ptextvalue1
)";

            this.ClearParameters();
            this.AddParameter("pheader1", DbType.String, headerText);
            this.AddParameter("pkey1", DbType.String, strgKey);
            this.AddParameter("ptextvalue1", DbType.String, strgValue);

            return base.ExecuteNonQuery(sql);
        }

        public int mergeSettings(string headerText, string strgKey, string strgValue)
        {
            if (this.isExistSetting(headerText, strgKey))
            {
                return this.updateDate(headerText, strgKey, strgValue);
            }
            else
            {
                return this.insertNew(headerText, strgKey, strgValue);
            }
        }

        #endregion

        #region //文字設定(複数行)

        public int insertNew(string headerText, string strgKey, int no, string strgValue)
        {
            string sql = @"insert into
                            settings(
                                HEADERTEXT
                                ,NO1
                                ,SETTINGKEY
                                ,TEXTVALUE
                            )
                            values(
                                @pheader
                                ,@pno
                                ,@pkey
                                ,@ptextvalue
                            )";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);
            this.AddParameter("pno", DbType.Int32, no);
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("ptextvalue", DbType.String, strgValue);

            return base.ExecuteNonQuery(sql);
        }


        #endregion

        #region //設定削除(複数行用)

        public int deleteSettings(string headerText, string strgKey)
        {
            string sql = @"delete from settings
                            where
                                SETTINGKEY like @pkey
                            and HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pkey", DbType.String, strgKey);
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }
        public int deleteSettings(string headerText)
        {
            string sql = @"delete from settings
                            where
                                HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }
        public int deleteHeader(string headerText)
        {
            string sql = @"delete from header
                            where
                                HEADERTEXT like @pheader";

            this.ClearParameters();
            this.AddParameter("pheader", DbType.String, headerText);

            return base.ExecuteNonQuery(sql);
        }
        
        #endregion

    }
}

で、実際に保存するまえに、LINQの拡張メソッドで、セーブ可能なコンポーネントをListに登録しておきます。

private List<IAccessSavable> Savables = new List<IAccessSavable>();

public void init()
{
            foreach (TabPage tab in this.tabCtrlScripts.TabPages)
            {
                //regist ↓タブコントロール配下のコントロールを一括登録
                this.Savables.AddRange(tab.Controls.OfType<IAccessSavable>());

                //set ext
                foreach (IAccessSavable savable in tab.Controls.OfType<IAccessSavable>())
                {
                    savable.Ext = this.Name.ToUpper();
                }
            }
}

で、実際のセーブとロード用メソッド

(コネクションプーリングを前提にしています)

        public void Save(DAOContext con, string header)
        {
            foreach (IAccessSavable savable in this.Savables)
            {
                savable.Save(con, header);
            }
        }

        public void Load(DAOContext con, string header)
        {
            foreach (IAccessSavable savable in this.Savables)
            {
                savable.Load(con, header);
            }
        }

で、実際にメイン関数に書くのは、以下。

(カスタムコントロールを書いていますが、そのLoad()、Save()メソッドで、上のSave()、Load()メソッドを呼ぶという形です)

            //Load
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                this.tabCustControl1.Load(con, header);
                con.CloseConnection();
            }
            //Save
            using (DAOContext con = new DAOContext(AccessConstring.SettingConString))
            {
                con.OpenConnection();
                this.tabCustControl1.Save(con, header);
                con.CloseConnection();
            }

トラックバック - http://d.hatena.ne.jp/kabacsharp/20131005

2013-07-27 ソート可能なデータソース

ソート可能なデータソース

| 16:35

f:id:kabacsharp:20130727163346p:image


テキトーなカスタムクラスのデータソースクラス作ったら、グリッドでソートできなかったので、調べてみました。

http://codezine.jp/article/detail/1159?p=2

さすがは先人の知恵。

上図のようにソートできるようになりました。

IComparerって「プログラミングC#」で、ほけーと読んでたけど、便利ですね。

VBからC#への変換はツールがありそうだけど、手作業で作ってみました。

        #region //comparer

        public class SampleComparer<T> : IComparer<T>
        {
            private ListSortDirection _direction;   //ソートの向き(昇順/降順)
            private PropertyDescriptor _property;   //ソート項目

            public SampleComparer(PropertyDescriptor prop, ListSortDirection direction)
            {
                this._property = prop;
                this._direction = direction;
            }

            //同値の場合ゼロを返します。
            int IComparer<T>.Compare(T objX, T objY)
            {
                //比較対象のオブジェクトからクリックしたプロパティを取得します。
                object valX = this.GetPropValue(objX, this._property.Name);
                object valY = this.GetPropValue(objY, this._property.Name);

                //directionの値(昇順/降順)に応じて取得した値を比較します。
                if (this._direction == ListSortDirection.Ascending)
                    return this.CompareAsc(valX, valY);
                else
                    return this.CompareDesc(valX, valY);
            }
            //昇順で比較を行います。
            private int CompareAsc(object valX, object valY)
            {
                return valX.ToString().CompareTo(valY.ToString());
            }

            //降順で比較を行います。
            private int CompareDesc(object valX, object valY)
            {
                return (this.CompareAsc(valX, valY) * -1);
            }

            //プロパティ値を取得します。
            private object GetPropValue(T val, string prop)
            {
                PropertyInfo propInfo = val.GetType().GetProperty(prop);
                return propInfo.GetValue(val, null);
            }

        }
        #endregion

        #region //BindingList
        public class SortBindingList<T> : BindingList<T>
        {

            private bool _isSorted; //ソート済みか否かを識別します。
            //ソート項目を保持します。
            private PropertyDescriptor _sortProperty;
            //ソート方向(昇順/降順)を保持します。
            private ListSortDirection _sortDirection;

            //リストをバインドします。
            public SortBindingList(T[] items)
            {
               
                ((List<T>)base.Items).AddRange(items);
            }

            //ソートが可能であることを公開します。
            //このプロパティがtrueで公開されないとソートが実行できません。
            protected override bool SupportsSortingCore
            {
                get
                {
                    return true;
                }
            }

            //ソートを実行します。
            protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
            {
                //ソートするためバインドされているリストを取得します。
                List<T> items = base.Items as List<T>;

                //リストがあった場合、
                //Comparerを生成してソート項目と項目名を渡します。
                if(items != null)
                {
                    SampleComparer<T> sc = new SampleComparer<T>(prop, direction);
                    items.Sort(sc);
                    //ソート済みに設定します。
                    this._isSorted = true;
                }
                else
                {
                    this._isSorted = false;
                }

                //ソート結果、方向を保持しておきます。
                this._sortProperty = prop;
                this._sortDirection = direction;

                //リストが変更(ソート)されたことをイベント通知します。
                this.OnListChanged(new ListChangedEventArgs( ListChangedType.ItemMoved, prop));

            }
        }
        #endregion

あとは、List<CustomClass>なんかを、コンストラクタに渡して、グリッドのDataSourceに代入するだけでOKでした。

            this.view.DataSource = new SortBindingList<CustomClass>(data.ToArray());
トラックバック - http://d.hatena.ne.jp/kabacsharp/20130727

2013-06-30 今更ながらC#でクリップボード使ってみましたあ

今更ながら、C#でクリップボードの実装をしました。

| 16:19

PDICみたいなクリップボード監視できないかなあ?とG先生に聞いてみたところ、下記サイトがありました。OSZありがたい

http://www.k4.dion.ne.jp/~anis7742/codevault/00130.html

早速委譲アダプタで実装です。

でも「Disposal必須」だそうで注意が必要です。

MyClipComboBox.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ABCS.UserClass
{
    public class MyClipComboBox : ComboBox, IDisposable
    {
        //クリップボード監視
        private ClipBoardWatcher cbwAdapter;

        public MyClipComboBox()
            : base()
        {
            this.cbwAdapter = new ClipBoardWatcher();
            this.cbwAdapter.DrawClipBoard += (sender, e2) =>
            {
                if (Clipboard.ContainsText())
                {
                    //this.listBox1.Items.Add(Clipboard.GetText());
                    String clipText = Clipboard.GetText();
                    if (!this.Items.Contains(clipText))
                    {
                        this.Items.Add(clipText);
                    }
                    this.SelectedItem = clipText;
                    //this.SelectedText = clipText;
                }
            };
        }

        protected override void Dispose(bool disposing)
        {
            this.cbwAdapter.Dispose();
            base.Dispose(disposing);
        }
    }
}

Disposal管理にヘルパーを実装。

単純なシングルトンです〜。

MyDisposalHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ABCS.UserClass
{
    public class MyDisposalHelper
    {
        private static List<IDisposable> shouldDisposes = new List<IDisposable>();

        private static MyDisposalHelper singleton = new MyDisposalHelper();
        MyDisposalHelper() { }

        public static MyDisposalHelper GetMyDisposalHelper()
        {
            return MyDisposalHelper.singleton;
        }
        public static void Add(IDisposable objDisposal )
        {
            MyDisposalHelper.shouldDisposes.Add(objDisposal);
        }
        public static void DoDispose()
        {
            foreach (IDisposable disposal in MyDisposalHelper.shouldDisposes)
            {
                disposal.Dispose();
            }
        }

    }
}

でメインフォームのOnLoadとOnClosingに下記記述を・・・

Form1.cs

private void Form1_Load(object sender, EventArgs e)
{
  //最後にdispose するオブジェクトの登録
  MyDisposalHelper.Add(this.cmbClipText);
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
  //クリップボード解放
  //this.cmbClipText.Dispose();
  MyDisposalHelper.DoDispose();
}
トラックバック - http://d.hatena.ne.jp/kabacsharp/20130630

2012-02-12 MyDummySQL ver0.04 NULL率設定できるようになりました。

MyDummySQL ver0.04 NULL率設定できるようになりました。

| 16:02

MyDummySQL、ver0.04になり、挿入時に列にNullを入れる確率を0%〜100%に設定できるようになりました。

ダウンロードは以下のURLからどうぞ。↓

http://la-bit.sakura.ne.jp/download/mydummysql/

動作確認はWindows7とWinXPModeで行っています。

f:id:kabacsharp:20120212155916p:image:w640

実行には.NETFramework4が必要です。↓

http://www.microsoft.com/downloads/ja-jp/details.aspx?FamilyID=9cfb2d51-5ff4-4491-b0e5-b386f32c0992

動作の様子の動画です。↓

D

トラックバック - http://d.hatena.ne.jp/kabacsharp/20120212