none
Page_Load中这样的异常为何捕捉不到,如何实现这样的效果? RRS feed

  • 问题

  • 页面中有一个DropDownList ddl_room,数据源绑定到一个sqldatasource上。
    想实现这样的效果:
    页面一打开,就让ddl_room选中某一项,如果这一项不存在时,就什么也不做。
    我在Page_Load事件中是这样写的
    ddl_room.SelectedValue = "列表中不存在的值";
    如果这个提供的值不存在的话,并不能被catch到
    最后返回一个错误页面,报告未处理的异常
    “ddl_room”有一个无效 SelectedValue,因为它不在项目列表中。
    参数名: value

    问题1. 要实现如果值不存在就什么也不做,或者默认选中第零项应该如何做呢?
    问题2. 为什么捕捉不到这个异常呢。

    其他事项:
    设断点看过,如果赋给一个存在的值的话,
    ddl_room.SelectedValue = "一个存在的值";
    执行完这句ddl_room.SelectedValue 仍然是="" (???)
    但当页面完全打开,ddl_room的选中项还是会乖乖的变成"一个存在的值"

    看资料好像是说和什么页面生存期有关
    因为Page_Load先执行,这时ddl_room中还没有任何项目。
    那样的话 问题1 应该如何实现呢。
    我不想再加个按钮,把Page_Load 中的代码写到按钮点击事件中。

    还请高人指点 谢谢!

    代码如下:
    protected void Page_Load(object sender, EventArgs e)
    {
       
        if (!IsPostBack)
        {
            try
            {
                ddl_room.SelectedValue = "不存在的值";
            }
            catch (Exception)
            {
                Literal1.Text = "";
            }           
        }
    }
    2009年4月30日 11:16

答案

  • 你好,只有在IsPostBack = true时才能引发异常,以下是 SelectedValue实现的源码, 希望对你有帮助

    public virtual string SelectedValue
     {
           get
           {
                 int num1 = this.SelectedIndex;
                 if (num1 >= 0)
                 {
                       return this.Items[num1].Value;
                }
                return string.Empty;
          }
          set
          {
                if (this.Items.Count != 0)
                {
                      if ((value == null) || (base.DesignMode && (value.Length == 0)))
                      {
                            this.ClearSelection();
                            return;
                      }
                      ListItem item1 = this.Items.FindByValue(value);
                      if ((((this.Page != null) && this.Page.IsPostBack) && this._stateLoaded) && (item1 == null))
                      {
                            throw new ArgumentOutOfRangeException("value", SR.GetString("ListControl_SelectionOutOfRange", new object[] { this.ID, "SelectedValue" }));
                      }
                      if (item1 != null)
                      {
                            this.ClearSelection();
                            item1.Selected = true;
                      }
                }
                this.cachedSelectedValue = value;
          }
    }


    知识改变命运,奋斗成就人生!
    2009年4月30日 11:58
    版主
  • 可能是数据绑定的原因,你试试在DropDownList的DataBind事件中写
    知识改变命运,奋斗成就人生!
    2009年4月30日 14:34
    版主

全部回复

  • 你好,只有在IsPostBack = true时才能引发异常,以下是 SelectedValue实现的源码, 希望对你有帮助

    public virtual string SelectedValue
     {
           get
           {
                 int num1 = this.SelectedIndex;
                 if (num1 >= 0)
                 {
                       return this.Items[num1].Value;
                }
                return string.Empty;
          }
          set
          {
                if (this.Items.Count != 0)
                {
                      if ((value == null) || (base.DesignMode && (value.Length == 0)))
                      {
                            this.ClearSelection();
                            return;
                      }
                      ListItem item1 = this.Items.FindByValue(value);
                      if ((((this.Page != null) && this.Page.IsPostBack) && this._stateLoaded) && (item1 == null))
                      {
                            throw new ArgumentOutOfRangeException("value", SR.GetString("ListControl_SelectionOutOfRange", new object[] { this.ID, "SelectedValue" }));
                      }
                      if (item1 != null)
                      {
                            this.ClearSelection();
                            item1.Selected = true;
                      }
                }
                this.cachedSelectedValue = value;
          }
    }


    知识改变命运,奋斗成就人生!
    2009年4月30日 11:58
    版主
  • 问题一,你可以这样试试看

    if (ddl_room.Items.Count > 0)
        ddl_room.SelectedIndex = 0;
    ddl_room.SelectedValue = "XXX";

    知识改变命运,奋斗成就人生!
    2009年4月30日 13:26
    版主
  • 你好大侠,谢谢你的回复。那段代码就是DropDownList的SelectedValue的源代码吗?太强了,怎么搞到的啊

    我试着把if (!IsPostBack)去掉,可是还是catch不到这个异常。
    我想利用Items.FindByValue(value)可以预先判断一下存在不存在这个值,不过判断加在在Load里好像也不行

    如何才能实现 问题1 啊?
    大侠们有没有碰到这种情况,是怎么处理的啊?

    //修改后代码如下:
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            ddl_room.SelectedValue = "不存在的值";
        }
        catch(Exception ex)
        {
            Literal1.Text = ex.Message;
        }       
    }

    2009年4月30日 13:32
  • 第一次加载时 IspostBack 是 false, 第二次才是 true, 也就是说你上面的代码是在 IsPostBact = false 时执行的

    知识改变命运,奋斗成就人生!
    2009年4月30日 13:35
    版主
  • 第一次加载时 IspostBack 是 false, 第二次才是 true, 也就是说你上面的代码是在 IsPostBact = false 时执行的

    知识改变命运,奋斗成就人生!

    哦 我明白了 谢谢
    不过 问题1 还是不知道应该怎么实现?
    我就想第一次打开的时候,如果给定的值存在就选中那个值,不存在就不进行选中这个操作。
    页面完全打开以后,用户可以随便选择ddl_room的其他项,就不会再有影响了。
    2009年4月30日 13:42
  • 方法一,你可以通过判断数据源中是否有此值来确定你下一步的操作
    方法二,你可以在 PageLoad中,为DropDownList添加一项比如叫"请选择" 设置这行为选中,然后再设SelectedValue
    要把 "请选择" 添加到第一项,你可以通过DropDownList.Item.Insert 来实现

    知识改变命运,奋斗成就人生!
    2009年4月30日 13:52
    版主
  • 谢谢你的提示
    方法一 可以实现我的要求。
    方法二 是我表达的不清楚。不进行选中这个操作,默认页面打开后就会选中第0项,这样就可以了。呵呵

    不过方法一还要在查询一下数据源,查询数据源时或者还有有什么更好的方法吗?
    如果过一阵没有更好的方法 我会标记答复的 谢谢啊
    2009年4月30日 14:05
  • 比如 ddl_room.Items.FindByValue(value);
    这个在第一次页面Load时能不能用上啊,查询数据源是不是必须再写个sqlcommand执行一下啊?
    2009年4月30日 14:15
  • 完成可以啊

                if (this.fList1.Items.FindByValue("XXXXXX") != null)
                    this.fList1.SelectedValue = "XXXXXX";

    知识改变命运,奋斗成就人生!
    2009年4月30日 14:18
    版主
  • 有没有 页面完全加载完了自动引发的事件啊?
    我想把 ddl_room.Items.FindByValue(value) 写到那里面
    如果不为空,再设置一下ddl_room的selectedValue 也可以啊
    2009年4月30日 14:21
  • 不用,写在 PageLoad里就好了, 这样就已经达到效果了

    if (!IsPostBack)
    {
         if (this.fList1.Items.FindByValue("XXXXXX") != null)
                    this.fList1.SelectedValue = "XXXXXX";
    }

    知识改变命运,奋斗成就人生!
    2009年4月30日 14:23
    版主
  • 完成可以啊

                if (this.fList1.Items.FindByValue("XXXXXX") != null)
                    this.fList1.SelectedValue = "XXXXXX";

    知识改变命运,奋斗成就人生!

    我这样写的,可是不行啊。
    好像没有执行这一句
    ddl_room.SelectedValue = "存在的值";


    protected void Page_Load(object sender, EventArgs e)
        {
            if (ddl_room.Items.FindByValue("存在的值") != null)
            {
                ddl_room.SelectedValue = "存在的值";
            }
        }
    2009年4月30日 14:28
  • 设断点ddl_room.Items.FindByValue("存在的值") 返回的就是null
    直到pageload完了 才突然有数据了 但是因为pageload的时候判断是false,里面的语句没有执行
    2009年4月30日 14:30
  • 地执行的,如果值中有XXXX才会执行,如果没有就不执行,你可以修改一下,没有时选中第一项

    if (!IsPostBack)
    {
         if (this.fList1.Items.FindByValue("XXXXXX") != null)
                    this.fList1.SelectedValue = "XXXXXX";
         else 
    this.fList1.SelectedIndex = 0
    }

    知识改变命运,奋斗成就人生!
    2009年4月30日 14:31
    版主
  • 可能是数据绑定的原因,你试试在DropDownList的DataBind事件中写
    知识改变命运,奋斗成就人生!
    2009年4月30日 14:34
    版主
  • 可能是数据绑定的原因,你试试在DropDownList的DataBind事件中写
    知识改变命运,奋斗成就人生!

    恩 完美解决了 太感谢了!
    2009年4月30日 14:40
  • 客气,客气,多多尝试:)
    知识改变命运,奋斗成就人生!
    2009年4月30日 14:41
    版主