private DataGridViewRow GetExpressionDetailViewRow( ExpressionData exp )
        {
            var row = new DataGridViewRow();
            row.CreateCells( ExpressionDetailView );

            row.SetValues(
                exp.Enabled,
                exp.LeftOperand,
                exp.RightOperand,
                exp.Operator
                );

            return row;
        }
        /// <summary>
        /// 指定された式から、式UIを初期化します。
        /// </summary>
        /// <param name="left">左辺値。</param>
        /// <param name="right">右辺値。指定しなければ null。</param>
        /// <param name="ope">演算子。指定しなければ null。</param>
        private void SetExpressionSetter( string left, object right = null, ExpressionData.ExpressionOperator? ope = null )
        {
            Type lefttype = ExpressionData.GetLeftOperandType( left );

            bool isenumerable = lefttype != null && lefttype != typeof( string ) && lefttype.GetInterface( "IEnumerable" ) != null;
            if ( isenumerable )
                lefttype = lefttype.GetElementType() ?? lefttype.GetGenericArguments().First();

            Description.Text = "";

            LeftOperand.SelectedValue = left;

            // 特殊判定(決め打ち)シリーズ
            if ( left == ".MasterShip.NameWithClass" ) {
                RightOperand_ComboBox.Visible = true;
                RightOperand_ComboBox.Enabled = true;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDown;
                RightOperand_NumericUpDown.Visible = false;
                RightOperand_NumericUpDown.Enabled = false;
                RightOperand_TextBox.Visible = false;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_string;

                RightOperand_ComboBox.DataSource = _dtRightOperand_shipname;
                RightOperand_ComboBox.Text = (string)( right ?? _dtRightOperand_shipname.AsEnumerable().First()["Display"] );

            } else if ( left == ".MasterShip.ShipType" ) {
                RightOperand_ComboBox.Visible = true;
                RightOperand_ComboBox.Enabled = true;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = false;
                RightOperand_NumericUpDown.Enabled = false;
                RightOperand_TextBox.Visible = false;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_bool;

                RightOperand_ComboBox.DataSource = _dtRightOperand_shiptype;
                RightOperand_ComboBox.SelectedValue = right == null ? 2 : right;

            } else if ( left.Contains( "SlotMaster" ) ) {
                RightOperand_ComboBox.Visible = true;
                RightOperand_ComboBox.Enabled = true;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = false;
                RightOperand_NumericUpDown.Enabled = false;
                RightOperand_TextBox.Visible = false;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_bool;

                RightOperand_ComboBox.DataSource = _dtRightOperand_equipment;
                RightOperand_ComboBox.SelectedValue = right == null ? 1 : right;

            } else if ( left == ".Range" ) {
                RightOperand_ComboBox.Visible = true;
                RightOperand_ComboBox.Enabled = true;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = false;
                RightOperand_NumericUpDown.Enabled = false;
                RightOperand_TextBox.Visible = false;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_number;

                RightOperand_ComboBox.DataSource = _dtRightOperand_range;
                RightOperand_ComboBox.SelectedValue = right == null ? 1 : right;

            } else if ( left == ".MasterShip.Speed" ) {
                RightOperand_ComboBox.Visible = true;
                RightOperand_ComboBox.Enabled = true;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = false;
                RightOperand_NumericUpDown.Enabled = false;
                RightOperand_TextBox.Visible = false;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_number;

                RightOperand_ComboBox.DataSource = _dtRightOperand_speed;
                RightOperand_ComboBox.SelectedValue = right == null ? 10 : right;

            } else if ( left == ".MasterShip.Rarity" ) {
                RightOperand_ComboBox.Visible = true;
                RightOperand_ComboBox.Enabled = true;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = false;
                RightOperand_NumericUpDown.Enabled = false;
                RightOperand_TextBox.Visible = false;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_number;

                RightOperand_ComboBox.DataSource = _dtRightOperand_rarity;
                RightOperand_ComboBox.SelectedValue = right == null ? 1 : right;

                // 以下、汎用判定
            } else if ( lefttype == null ) {
                RightOperand_ComboBox.Visible = false;
                RightOperand_ComboBox.Enabled = false;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = false;
                RightOperand_NumericUpDown.Enabled = false;
                RightOperand_TextBox.Visible = true;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = false;
                Operator.DataSource = _dtOperator;

                RightOperand_TextBox.Text = right == null ? "" : right.ToString();

            } else if ( lefttype == typeof( int ) ) {
                RightOperand_ComboBox.Visible = false;
                RightOperand_ComboBox.Enabled = false;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = true;
                RightOperand_NumericUpDown.Enabled = true;
                RightOperand_TextBox.Visible = false;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_number;

                RightOperand_NumericUpDown.DecimalPlaces = 0;
                RightOperand_NumericUpDown.Increment = 1m;

                switch ( left ) {
                    case ".MasterID":
                        RightOperand_NumericUpDown.Minimum = 0;
                        RightOperand_NumericUpDown.Maximum = 999999;
                        break;
                    case ".Level":
                        RightOperand_NumericUpDown.Minimum = 1;
                        RightOperand_NumericUpDown.Maximum = 150;
                        break;
                    case ".ExpTotal":
                    case ".ExpNextRemodel":
                        RightOperand_NumericUpDown.Minimum = 0;
                        RightOperand_NumericUpDown.Maximum = 4360000;
                        break;
                    case ".ExpNext":
                        RightOperand_NumericUpDown.Minimum = 0;
                        RightOperand_NumericUpDown.Maximum = 195000;
                        break;
                    case ".HPCurrent":
                    case ".HPMax":
                        RightOperand_NumericUpDown.Minimum = 0;
                        RightOperand_NumericUpDown.Maximum = 999;
                        break;
                    case ".Condition":
                        RightOperand_NumericUpDown.Minimum = 0;
                        RightOperand_NumericUpDown.Maximum = 100;
                        break;
                    case ".RepairingDockID":
                        RightOperand_NumericUpDown.Minimum = -1;
                        RightOperand_NumericUpDown.Maximum = 4;
                        Description.Text = "-1=未入渠, 1~4=入渠中(ドック番号)";
                        break;
                    case ".RepairTime":
                        RightOperand_NumericUpDown.Minimum = 0;
                        RightOperand_NumericUpDown.Maximum = int.MaxValue;
                        RightOperand_NumericUpDown.Increment = 60000;
                        break;
                    case ".SlotSize":
                        RightOperand_NumericUpDown.Minimum = 0;
                        RightOperand_NumericUpDown.Maximum = 5;
                        break;
                    default:
                        RightOperand_NumericUpDown.Minimum = 0;
                        RightOperand_NumericUpDown.Maximum = 9999;
                        break;
                }
                RightOperand_NumericUpDown.Value = right == null ? RightOperand_NumericUpDown.Minimum : (int)right;
                UpdateDescriptionFromNumericUpDown();

            } else if ( lefttype == typeof( double ) ) {
                RightOperand_ComboBox.Visible = false;
                RightOperand_ComboBox.Enabled = false;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = true;
                RightOperand_NumericUpDown.Enabled = true;
                RightOperand_TextBox.Visible = false;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_number;

                switch ( left ) {
                    case ".HPRate":
                    case ".AircraftRate[0]":
                    case ".AircraftRate[1]":
                    case ".AircraftRate[2]":
                    case ".AircraftRate[3]":
                    case ".AircraftRate[4]":
                    case ".AircraftTotalRate":
                    case ".FuelRate":
                    case ".AmmoRate":
                        RightOperand_NumericUpDown.Minimum = 0;
                        RightOperand_NumericUpDown.Maximum = 1;
                        RightOperand_NumericUpDown.DecimalPlaces = 2;
                        RightOperand_NumericUpDown.Increment = 0.01m;
                        break;
                    default:
                        RightOperand_NumericUpDown.Maximum = int.MaxValue;
                        RightOperand_NumericUpDown.Minimum = int.MinValue;
                        RightOperand_NumericUpDown.DecimalPlaces = 0;
                        RightOperand_NumericUpDown.Increment = 1m;
                        break;
                }
                RightOperand_NumericUpDown.Value = right == null ? RightOperand_NumericUpDown.Minimum : Convert.ToDecimal( right );
                UpdateDescriptionFromNumericUpDown();

            } else if ( lefttype == typeof( bool ) ) {
                RightOperand_ComboBox.Visible = true;
                RightOperand_ComboBox.Enabled = true;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = false;
                RightOperand_NumericUpDown.Enabled = false;
                RightOperand_TextBox.Visible = false;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_bool;

                RightOperand_ComboBox.DataSource = _dtRightOperand_bool;
                RightOperand_ComboBox.SelectedValue = right == null ? true : right;

            } else if ( lefttype.IsEnum ) {
                RightOperand_ComboBox.Visible = true;
                RightOperand_ComboBox.Enabled = true;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = false;
                RightOperand_NumericUpDown.Enabled = false;
                RightOperand_TextBox.Visible = false;
                RightOperand_TextBox.Enabled = false;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_bool;

                DataTable dt = new DataTable();
                dt.Columns.AddRange( new DataColumn[]{
                    new DataColumn( "Value", typeof( string ) ),
                    new DataColumn( "Display", typeof( string ) ) } );
                var names = lefttype.GetEnumNames();
                var values = lefttype.GetEnumValues();
                for ( int i = 0; i < names.Length; i++ )
                    dt.Rows.Add( values.GetValue( i ), names[i] );
                dt.AcceptChanges();
                RightOperand_ComboBox.DataSource = dt;
                RightOperand_ComboBox.SelectedValue = right;

            } else {
                RightOperand_ComboBox.Visible = false;
                RightOperand_ComboBox.Enabled = false;
                RightOperand_ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
                RightOperand_NumericUpDown.Visible = false;
                RightOperand_NumericUpDown.Enabled = false;
                RightOperand_TextBox.Visible = true;
                RightOperand_TextBox.Enabled = true;
                Operator.Enabled = true;
                Operator.DataSource = _dtOperator_string;

                RightOperand_TextBox.Text = right == null ? "" : right.ToString();

            }

            if ( isenumerable ) {
                Operator.DataSource = _dtOperator_array;
            }

            if ( Operator.DataSource as DataTable != null ) {
                if ( ope == null ) {
                    Operator.SelectedValue = ( (DataTable)Operator.DataSource ).AsEnumerable().First()["Value"];
                } else {
                    Operator.SelectedValue = (ExpressionData.ExpressionOperator)ope;
                }
            }
        }
        /// <summary>
        /// UIの設定値からExpressionDataを構築します。
        /// </summary>
        private ExpressionData BuildExpressionDataFromUI()
        {
            var exp = new ExpressionData();
            exp.LeftOperand = (string)LeftOperand.SelectedValue ?? LeftOperand.Text;
            exp.Operator = (ExpressionData.ExpressionOperator)Operator.SelectedValue;

            Type type = exp.GetLeftOperandType();
            if ( type != null && type != typeof( string ) && type.GetInterface( "IEnumerable" ) != null )
                type = type.GetElementType() ?? type.GetGenericArguments().First();

            if ( RightOperand_ComboBox.Enabled ) {
                if ( RightOperand_ComboBox.DropDownStyle == ComboBoxStyle.DropDownList )
                    exp.RightOperand = Convert.ChangeType( RightOperand_ComboBox.SelectedValue ?? RightOperand_ComboBox.Text, type );
                else
                    exp.RightOperand = Convert.ChangeType( RightOperand_ComboBox.Text, type );

            } else if ( RightOperand_NumericUpDown.Enabled ) {
                exp.RightOperand = Convert.ChangeType( RightOperand_NumericUpDown.Value, type );

            } else if ( RightOperand_TextBox.Enabled ) {
                exp.RightOperand = Convert.ChangeType( RightOperand_TextBox.Text, type );

            } else {
                exp.RightOperand = null;
            }

            return exp;
        }