// 清除一个Item2对象对应的Control
        public void ClearOneItemControls(
            TableLayoutPanel table,
            Item2 line)
        {
            // color
            Label label = line.label_color;
            table.Controls.Remove(label);

            // catalog no
            table.Controls.Remove(line.textBox_catalogNo);

            // seller
            table.Controls.Remove(line.comboBox_seller);

            // source
            table.Controls.Remove(line.comboBox_source);

            // range
            table.Controls.Remove(line.dateRange_range);

            // issue count
            table.Controls.Remove(line.comboBox_issueCount);

            // copy
            table.Controls.Remove(line.comboBox_copy);

            // price
            table.Controls.Remove(line.textBox_price);

            // location
            table.Controls.Remove(line.location);

            // class
            table.Controls.Remove(line.comboBox_class);

            // seller address
            table.Controls.Remove(line.label_sellerAddress);

            // other
            table.Controls.Remove(line.label_other);
        }
        public void RangeSelectItem(Item2 element)
        {
            Item2 start = this.LastClickItem;

            int nStart = this.Items.IndexOf(start);
            if (nStart == -1)
                return;

            int nEnd = this.Items.IndexOf(element);

            if (nStart > nEnd)
            {
                // 交换
                int nTemp = nStart;
                nStart = nEnd;
                nEnd = nTemp;
            }

            for (int i = nStart; i <= nEnd; i++)
            {
                Item2 cur_element = this.Items[i];

                if ((cur_element.State & ItemState.Selected) == 0)
                    cur_element.State |= ItemState.Selected;
            }

            // 清除其余位置
            for (int i = 0; i < nStart; i++)
            {
                Item2 cur_element = this.Items[i];

                if ((cur_element.State & ItemState.Selected) != 0)
                    cur_element.State -= ItemState.Selected;
            }

            for (int i = nEnd + 1; i < this.Items.Count; i++)
            {
                Item2 cur_element = this.Items[i];

                if ((cur_element.State & ItemState.Selected) != 0)
                    cur_element.State -= ItemState.Selected;
            }
        }
        // 获得一个未曾使用的index字符串
        // paremeters:
        //      exclude 查阅过程中,排除此项。如果不需要本参数(即不排除任何事项),用使用值null
        string GetNewIndex(Item2 exclude)
        {
            for (int j = 1; ; j++)
            {
                string strIndex = j.ToString();

                bool bFound = false;
                for (int i = 0; i < this.Items.Count; i++)
                {
                    Item2 item = this.Items[i];

                    if (item == exclude)
                        continue;

                    if (item.Index == strIndex)
                    {
                        bFound = true;
                        break;
                    }
                }

                if (bFound == false)
                    return strIndex;
            }
        }
        public void ToggleSelectItem(Item2 element)
        {
            // 选中当前行
            if ((element.State & ItemState.Selected) == 0)
                element.State |= ItemState.Selected;
            else
                element.State -= ItemState.Selected;

            this.LastClickItem = element;
        }
        public void SelectItem(Item2 element,
            bool bClearOld)
        {

            if (bClearOld == true)
            {
                for (int i = 0; i < this.Items.Count; i++)
                {
                    Item2 cur_element = this.Items[i];

                    if (cur_element == element)
                        continue;   // 暂时不处理当前行

                    if ((cur_element.State & ItemState.Selected) != 0)
                        cur_element.State -= ItemState.Selected;
                }
            }

            // 选中当前行
            if ((element.State & ItemState.Selected) == 0)
                element.State |= ItemState.Selected;

            this.LastClickItem = element;
        }
        public void RemoveItem(Item2 line)
        {
            int index = this.Items.IndexOf(line);

            if (index == -1)
                return;

            line.RemoveFromTable(this.dpTable1, index);

            this.Items.Remove(line);

            /*
            if (this.LastClickItem == line)
                this.LastClickItem = null;
             * */

            this.Changed = true;
        }
        public Item2 InsertNewItem(int index)
        {
            this.DisableUpdate();   // 防止闪动。彻底解决问题。2009/10/13 

            try
            {
                Item2 item = new Item2(this);

                item.AddToTable(this.dpTable1, index);

                this.Items.Insert(index, item);

                if (this.GetDefaultRecord != null)
                {
                    GetDefaultRecordEventArgs e = new GetDefaultRecordEventArgs();
                    this.GetDefaultRecord(this, e);

                    string strDefaultRecord = e.Xml;

                    if (String.IsNullOrEmpty(strDefaultRecord) == true)
                        goto END1;

                    string strError = "";
                    // 根据缺省XML订购记录填充必要的字段
                    int nRet = SetDefaultRecord(item,
                        strDefaultRecord,
                        true,
                        out strError);
                    if (nRet == -1)
                        throw new Exception(strError);
                }
            END1:

                item.State = ItemState.New;

                return item;
            }
            finally
            {
                this.EnableUpdate();
            }
        }
        // 根据缺省XML订购记录填充必要的字段
        int SetDefaultRecord(Item2 item,
            string strDefaultRecord,
            bool bResetIndexValue,
            out string strError)
        {
            strError = "";

            if (String.IsNullOrEmpty(strDefaultRecord) == true)
                return 0;

            XmlDocument dom = new XmlDocument();
            try
            {
                dom.LoadXml(strDefaultRecord);
            }
            catch (Exception ex)
            {
                strError = "XML记录装入DOM时出错: " + ex.Message;
                return -1;
            }

            // catalog no
            item.CatalogNo = DomUtil.GetElementText(dom.DocumentElement,
                "catalogNo");

            // seller
            item.Seller = DomUtil.GetElementText(dom.DocumentElement,
                "seller");

            // range
            try
            {
                item.RangeString = DomUtil.GetElementText(dom.DocumentElement,
                    "range");
            }
            catch (Exception ex)
            {
                // 2008/12/18
                strError = ex.Message;
                return -1;
            }

            item.IssueCountString = DomUtil.GetElementText(dom.DocumentElement,
                "issueCount");

            // source
            string strSource = DomUtil.GetElementText(dom.DocumentElement,
                "source");

            string strNewSource = "";
            string strOldSource = "";
            ParseOldNewValue(strSource,
                out strOldSource,
                out strNewSource);

            if (String.IsNullOrEmpty(strNewSource) == true) // 没有新值的时候用旧值作为初始值
                item.Source = strOldSource;
            else
                item.Source = strNewSource;

            item.OldSource = strOldSource;


            // distribute string
            // 注意:必须在copy前设置,因为copy string中可能包含勾选location item的信息,如果copy string先设置,勾选好的状态会被后来重设distribute string而冲掉
            string strDistribute = DomUtil.GetElementText(dom.DocumentElement,
                "distribute");

            item.Distribute = strDistribute;

            // copy
            // 注:copy值是按照XML记录来设置的。一般设置为可能的最大值
            string strCopy = DomUtil.GetElementText(dom.DocumentElement,
                    "copy");

            string strNewCopy = "";
            string strOldCopy = "";
            ParseOldNewValue(strCopy,
                out strOldCopy,
                out strNewCopy);

            /*
            if (String.IsNullOrEmpty(strNewCopy) == true) // 没有新值的时候用旧值作为初始值
                item.CopyString = strOldCopy;
            else
                item.CopyString = strNewCopy;

            item.OldCopyString = strOldCopy;
             * */

            // 2008/11/3 changed
            if (this.ArriveMode == false)
            {
                // 订购时,用旧价格
                item.CopyString = strOldCopy;
                item.OldCopyString = strOldCopy;
            }
            else
            {
                // 2008/10/19 changed
                // 验收时,新旧价格都分明
                if (String.IsNullOrEmpty(strNewCopy) == false)
                    item.CopyString = strNewCopy;

                if (String.IsNullOrEmpty(strOldCopy) == false)
                    item.OldCopyString = strOldCopy;
            }


            // 限制馆藏地点事项的个数
            int nMaxCopyValue = Math.Max(item.CopyValue, item.OldCopyValue);

            if (nMaxCopyValue < item.DistributeCount)
                item.DistributeCount = nMaxCopyValue;

            /*
            // 限制馆藏地点事项的个数
            try
            {
                strDistribute = LocationEditControl.CanonicalizeDistributeString(
                    strDistribute,
                    item.CopyValue);
            }
            catch (Exception ex)
            {
                strError = ex.Message;
                return -1;
            }*/


            // price
            string strPrice = DomUtil.GetElementText(dom.DocumentElement,
                "price");

            string strNewPrice = "";
            string strOldPrice = "";
            ParseOldNewValue(strPrice,
                out strOldPrice,
                out strNewPrice);

            if (String.IsNullOrEmpty(strNewPrice) == true) // 没有新值的时候用旧值作为初始值
                item.Price = strOldPrice;
            else
                item.Price = strNewPrice;

            item.OldPrice = strOldPrice;




            // class
            item.Class = DomUtil.GetElementText(dom.DocumentElement,
                "class");


            // 设置好 已订购 状态
            string strState = DomUtil.GetElementText(dom.DocumentElement,
                "state");

            if (this.ArriveMode == false)
            {
                // 订购态

                // 注:只有未订购的、草稿状态的事项才允许修改订购
                // 已订购(必然是全部发出,不可能局部发出),或者已验收(有可能是局部验收,或者(虽然已验收完但是)潜在可以追加),这样的事项都不能再进行任何订购操作,所以为readonly

                if (strState == "已订购" || strState == "已验收")
                    item.State |= ItemState.ReadOnly;
            }
            else
            {
                // 验收态
                if (strState == "已订购" || strState == "已验收")
                {
                    // 注:状态为“已验收”时,不一定全部复本都已验收,所以这时应当允许再次验收。
                    // 即便所有复本都已验收,还可以追加、多验收复本,所以这样的事项不能readonly

                    // item.State -= ItemState.ReadOnly;

                    // 将location item中已经勾选的事项设置为readonly态,表示是已经验收的(馆藏地点、册)事项
                    item.location.SetAlreadyCheckedToReadOnly(false);

                }
                else
                {
                    // 一般而言可能出现了空白的状态值,这表明尚未订出,还属于草稿记录,自然也就无从验收了

                    item.State |= ItemState.ReadOnly;
                }

            }
            
            // 2009/2/13
            try
            {
                item.SellerAddressXml = DomUtil.GetElementOuterXml(dom.DocumentElement, "sellerAddress");
            }
            catch (Exception ex)
            {
                strError = "设置SellerAddressXml时发生错误: " + ex.Message;
                return -1;
            }

            try
            {
                item.OtherXml = strDefaultRecord;
            }
            catch (Exception ex)
            {
                strError = "设置OtherXml时发生错误: " + ex.Message;
                return -1;
            }

            if (bResetIndexValue == true)
            {
                // 修正index
                item.Index = GetNewIndex(item);
            }

            return 0;
        }