DataGrid中点击超级链接列后,如何控制弹出窗口????/(MENGZI)

aspx

------------------------------------------------------

<%@ Page language="c#" EnableViewState = "true" Src="~/default.aspx.cs"
 AutoEventWireup="false" Inherits="eMeng.Exam.DataGridPaging.DataGridPaging" %>
  <script   language="javascript">  
  var   eid;  
  function   openwins()  
  {  
  showModalDialog("addinsulator.aspx?id=0",window,'dialogWidth:560px;dialogHeight:300px;center:yes;help:no;resizable:no;status:no');  
  }  
  function   openwin(eid)  
  {  
  showModalDialog("addinsulator.aspx?id="+eid+"&temp="+Math.random(),window,'dialogWidth:560px;dialogHeight:300px;center:yes;help:no;resizable:no;status:no');  
  }  
  </script>
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" runat="server">
<asp:datagrid id="MyDataGrid" runat="server" AutoGenerateColumns="False"
 HorizontalAlign="Center" AlternatingItemStyle-BackColor="#eeeeee"
 HeaderStyle-BackColor="#aaaadd" Font-Size="8pt" Font-Name="Verdana"
 CellSpacing="0" CellPadding="3" GridLines="Both" BorderWidth="1"
 BorderColor="black" OnPageIndexChanged="MyDataGrid_Page" PagerStyle-HorizontalAlign="Right"
 PagerStyle-Mode="NumericPages" PageSize="15" AllowPaging="True">
  <AlternatingItemStyle BackColor="#EEEEEE"></AlternatingItemStyle>
  <HeaderStyle BackColor="#AAAADD" Font-Bold="True" HorizontalAlign="Center"></HeaderStyle>
  <PagerStyle HorizontalAlign="Right" Mode="NumericPages"></PagerStyle>
  <Columns>
  <asp:BoundColumn HeaderText="產品編號" DataField="productid" HeaderStyle-Width="80px">
  </asp:BoundColumn>
  <asp:BoundColumn HeaderText="產品名稱" DataField="productname">
  </asp:BoundColumn>

  <asp:BoundColumn HeaderText="描述" DataField="intro">
  </asp:BoundColumn>
 
  <asp:hyperlinkcolumn   datanavigateurlfield="productprice" 
   datanavigateurlformatstring="javascript:openwin({0})" 
   datatextfield="productprice"   headertext="價格"></asp:hyperlinkcolumn>
 
  </Columns>
 
</asp:datagrid>
<p style="FONT-SIZE:9pt" align="center">
  <asp:label id="lblPageCount" runat="server"></asp:label>&nbsp;
  <asp:label id="lblCurrentIndex" runat="server"></asp:label>
  <asp:linkbutton id="btnFirst" onclick="PagerButtonClick" runat="server" Font-Name="verdana"
   Font-size="8pt" ForeColor="navy" CommandArgument="0"></asp:linkbutton>&nbsp;
  <asp:linkbutton id="btnPrev"  onclick="PagerButtonClick" runat="server" Font-Name="verdana"
   Font-size="8pt" ForeColor="navy" CommandArgument="prev"></asp:linkbutton>&nbsp;
  <asp:linkbutton id="btnNext" onclick="PagerButtonClick" runat="server" Font-Name="verdana"
   Font-size="8pt" ForeColor="navy" CommandArgument="next"></asp:linkbutton>&nbsp;
  <asp:linkbutton id="btnLast" onclick="PagerButtonClick" runat="server" Font-Name="verdana"
   Font-size="8pt" ForeColor="navy" CommandArgument="last"></asp:linkbutton>
</p>
</form>
</body>
</HTML>
----------------------------------------------------------------

aspx.cs

------------------------------------------------------

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
namespace eMeng.Exam.DataGridPaging
{
    /// <summary>
    /// DataGridPaging 的摘要说明。
    /// </summary>
    public class DataGridPaging : System.Web.UI.Page
    {
        protected System.Web.UI.WebControls.DataGrid MyDataGrid;
        protected System.Web.UI.WebControls.Label lblPageCount;
        protected System.Web.UI.WebControls.Label lblCurrentIndex;
        protected System.Web.UI.WebControls.LinkButton btnFirst;
        protected System.Web.UI.WebControls.LinkButton btnPrev;
        protected System.Web.UI.WebControls.LinkButton btnNext;
        protected System.Web.UI.WebControls.LinkButton btnLast;
        private SqlConnection cn = new SqlConnection();

        private void Page_Load(object sender, System.EventArgs e)
        {
            // 在此处放置用户代码以初始化页面
            btnFirst.Text = "最首页";
            btnPrev.Text = "前一页";
            btnNext.Text = "下一页";
            btnLast.Text = "最后页";
            OpenDatabase();
            BindGrid();
        }
        private void OpenDatabase()
        {
            cn.ConnectionString = "server=(local);database=eshop;user=jackey;pwd=chenzhao";
            cn.Open();
        }
        private void ShowStats()
        {
            lblCurrentIndex.Text = "第 " + (MyDataGrid.CurrentPageIndex + 1).ToString() + " 页";
            lblPageCount.Text = "总共 " + MyDataGrid.PageCount.ToString() + " 页";
        }

        public void PagerButtonClick(object sender, EventArgs e)
        {
            string arg = ((LinkButton)sender).CommandArgument.ToString();
            switch (arg)
            {
                case "next":
                    if (MyDataGrid.CurrentPageIndex < (MyDataGrid.PageCount - 1))
                    {
                        MyDataGrid.CurrentPageIndex += 1;
                    }
                    break;
                case "prev":
                    if (MyDataGrid.CurrentPageIndex > 0)
                    {
                        MyDataGrid.CurrentPageIndex -= 1;
                    }
                    break;
                case "last":
                    MyDataGrid.CurrentPageIndex = (MyDataGrid.PageCount - 1);
                    break;
                default:
                    MyDataGrid.CurrentPageIndex = System.Convert.ToInt32(arg);
                    break;
            }
            BindGrid();
            ShowStats();
        }
        public void BindGrid()
        {
         SqlConnection myConnection = cn;
            DataSet ds = new DataSet();
            SqlDataAdapter adapter = new SqlDataAdapter("select * from productinfo", myConnection);
            adapter.Fill(ds, "Document");
            MyDataGrid.DataSource = ds.Tables["Document"].DefaultView;
            MyDataGrid.DataBind();
            ShowStats();
        }
        public void MyDataGrid_Page(object sender, DataGridPageChangedEventArgs e)
        {
            int startIndex;
            startIndex = MyDataGrid.CurrentPageIndex * MyDataGrid.PageSize;
            MyDataGrid.CurrentPageIndex = e.NewPageIndex;
            BindGrid();
            ShowStats();
        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            //
            // CODEGEN:该调用是 ASP.NET Web 窗体设计器所必需的。
            //
            InitializeComponent();
            base.OnInit(e);
        }

        /// <summary>
        /// 设计器支持所需的方法 - 不要使用代码编辑器修改
        /// 此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.Load += new System.EventHandler(this.Page_Load);

        }
        #endregion
    }
}
 

<think> 我们之前讨论了如何通过双击实现DataGrid整行编辑,现在用户的问题是:如何在WPF DataGrid中实现行级别的编辑启用/禁用控制?即根据某些条件,允许或禁止编辑特定的行。 根据引用[3]中提到的,DataGrid可以自定义,并且可以通过绑定来控制编辑状态。但用户需要的是行级别的控制,即整行的编辑状态(允许或禁止编辑)。 实现行级别编辑启用/禁用控制的方法: 1. **使用DataGrid的RowStyle属性**:通过设置DataGridRow的IsEnabled属性或者通过样式触发器来控制行是否可编辑。 注意:直接禁用整行(IsEnabled=False)会使得整行变灰,且用户无法与行内任何控件交互。如果只是希望禁止编辑但保持其他交互(如选择),则需要更精细的控制。 2. **通过数据对象的属性来控制**:在数据对象中增加一个布尔属性(例如IsEditable),然后在的编辑元素(如TextBox)上绑定IsReadOnly属性,并设置转换器(根据行的IsEditable和本身的只读设置等)。 但是,这样需要在每一都做绑定,比较繁琐。 3. **使用DataGrid的BeginningEdit事件**:在事件中根据条件取消编辑操作。 4. **通过自定义DataGridRow的样式,结合IsEnabled或IsHitTestVisible等属性**:但同样会影响整行的交互。 5. **利用DataGridRow的IsEnabled绑定到数据对象的某个属性**:这样可以根据数据对象的属性来禁用整行,但注意这样会同时禁用行内的所有控件。 下面分别介绍这几种方法: ### 方法1:使用BeginningEdit事件取消编辑 这种方法可以灵活地根据行数据条件决定是否允许编辑。 ```csharp private void DataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) { // 获取当前行的数据对象 var dataItem = e.Row.Item; // 假设数据对象有一个属性IsEditable,根据这个属性判断是否允许编辑 if (dataItem is YourDataType item && !item.IsEditable) { e.Cancel = true; // 取消编辑 } } ``` 在XAML中,给DataGrid添加事件: ```xml <DataGrid BeginningEdit="DataGrid_BeginningEdit" ... /> ``` 优点:实现简单,可以精确控制每一行。 缺点:只能阻止用户通过界面编辑(例如双击单元格),如果程序以代码方式调用BeginEdit,则不会触发此事件。 ### 方法2:通过行样式禁用整行(包括选择等) 如果希望整行不可编辑且不可交互(包括不能被选择),则可以将行的IsEnabled绑定到数据对象的属性。 在DataGrid中设置ItemContainerStyle: ```xml <DataGrid> <DataGrid.ItemContainerStyle> <Style TargetType="DataGridRow"> <Setter Property="IsEnabled" Value="{Binding IsEditable}" /> </Style> </DataGrid.ItemContainerStyle> </DataGrid> ``` 注意:这样设置后,如果某行的IsEditable为false,则该行会变灰,且无法被选中。 如果希望允许行可以被选中(但不能编辑),则需要使用其他方法。 ### 方法3:只禁用编辑但允许选择(推荐) 结合方法1(BeginningEdit事件)可以做到只禁止编辑而不影响选择。 但是,如果希望同时控制单元格的显示(例如将单元格置灰),则需要在单元格样式上做文章。 我们可以通过的ElementStyle和EditingElementStyle来设置非编辑状态和编辑状态的样式,根据行数据的状态来改变单元格的外观。 例如,对于DataGridTextColumn: ```xml <DataGridTextColumn Binding="{Binding Name}"> <DataGridTextColumn.ElementStyle> <Style TargetType="TextBlock"> <Style.Triggers> <DataTrigger Binding="{Binding IsEditable}" Value="False"> <Setter Property="Foreground" Value="Gray" /> </DataTrigger> </Style.Triggers> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn> ``` 这样,当行的IsEditable为false时,该单元格的文本显示为灰色,但双击时仍然会进入编辑(因为本身没有阻止编辑)。所以需要配合BeginningEdit事件来阻止编辑。 因此,完整的方案是: 1. 使用BeginningEdit事件阻止编辑。 2. 使用样式改变不可编辑行的单元格外观。 ### 方法4:通过自定义和单元格模板 如果使用DataGridTemplateColumn,可以在模板中根据IsEditable设置控件的IsEnabled或IsReadOnly。 例如: ```xml <DataGridTemplateColumn> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Name}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox Text="{Binding Name}" IsReadOnly="{Binding IsEditable, Converter={StaticResource InverseBooleanConverter}}" /> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> ``` 这里,在编辑模板中,TextBox的IsReadOnly绑定到IsEditable(注意需要取反,所以需要转换器)。这样,当行的IsEditable为false时,编辑状态下文本框也是只读的。 这种方法需要为每一都这样设置,并且需要写转换器(将IsEditable取反,因为IsReadOnly true表示只读,而IsEditable false时我们希望只读)。 优点:可以逐控制,但缺点是需要为每一都配置,比较繁琐。 根据用户的需求(行级别的编辑启用/禁用),我们推荐使用方法1(全局阻止编辑事件)配合方法3(改变不可编辑行的外观)来实现。 步骤总结: 1. 在数据对象中增加一个布尔属性IsEditable。 2. 为DataGrid添加BeginningEdit事件,在事件处理中检查当前行的IsEditable属性,如果为false则取消编辑。 3. 为每一(或至少需要控制编辑的)添加ElementStyle,使用DataTrigger根据IsEditable改变不可编辑单元格的外观(如文字灰色)。 这样,用户尝试编辑不可编辑行时会被阻止,并且不可编辑行有视觉上的区分。 ### 示例代码 假设数据对象: ```csharp public class Item : INotifyPropertyChanged { private string _name; public string Name { get => _name; set { _name = value; OnPropertyChanged(); } } private bool _isEditable = true; public bool IsEditable { get => _isEditable; set { _isEditable = value; OnPropertyChanged(); } } // INotifyPropertyChanged 实现 } ``` XAML中: ```xml <DataGrid ItemsSource="{Binding Items}" BeginningEdit="DataGrid_BeginningEdit" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="Name" Binding="{Binding Name}"> <DataGridTextColumn.ElementStyle> <Style TargetType="TextBlock"> <Style.Triggers> <DataTrigger Binding="{Binding IsEditable}" Value="False"> <Setter Property="Foreground" Value="Gray" /> </DataTrigger> </Style.Triggers> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn> <!-- 其他类似 --> </DataGrid.Columns> </DataGrid> ``` 事件处理: ```csharp private void DataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) { if (e.Row.Item is Item item && !item.IsEditable) { e.Cancel = true; } } ``` 这样,当某行的IsEditable为false时,该行的Name显示为灰色,并且双击该行(或该单元格)时不会进入编辑模式。 注意:如果希望整行都不可编辑,则需要为每一都设置类似的ElementStyle(改变外观)并且BeginningEdit事件已经阻止了所有的编辑。 另外,如果希望控制行头或者整行的背景色等,可以在DataGridRow的样式中使用触发器。 例如,改变不可编辑行的背景色: ```xml <DataGrid> <DataGrid.ItemContainerStyle> <Style TargetType="DataGridRow"> <Style.Triggers> <DataTrigger Binding="{Binding IsEditable}" Value="False"> <Setter Property="Background" Value="LightGray" /> </DataTrigger> </Style.Triggers> </Style> </DataGrid.ItemContainerStyle> <!-- 定义 --> </DataGrid> ``` 这样,不可编辑行的背景会变为浅灰色。 根据引用[2],如果性能成为问题(特别是在低配电脑上),请注意虚拟化等优化措施。 综上所述,我们通过结合BeginningEdit事件和样式触发器,实现了行级别的编辑控制。 --- §§相关问题§§ 1. 如何实现DataGrid单元格级别的编辑控制? 2. WPF DataGrid中如何根据数据对象动态改变行样式? 3. DataGrid的BeginningEdit和PreparingCellForEdit事件有什么区别? 4. 如何优化具有复杂样式的DataGrid性能? 5. 如何在DataGrid中实现编辑状态的全局管理? </think> ### WPF DataGrid实现行级别编辑启用/禁用控制的方法 #### 1. **使用数据对象属性绑定(推荐)** 在数据模型中添加`IsEditable`属性,通过绑定控制整行编辑状态: ```csharp public class DataItem : INotifyPropertyChanged { private bool _isEditable = true; public bool IsEditable { get => _isEditable; set { _isEditable = value; OnPropertyChanged(); } } // 其他属性... } ``` 在XAML中通过样式绑定: ```xml <DataGrid> <DataGrid.ItemContainerStyle> <Style TargetType="DataGridRow"> <Setter Property="IsEnabled" Value="{Binding IsEditable}"/> </Style> </DataGrid.ItemContainerStyle> </DataGrid> ``` #### 2. **使用样式触发器动态控制** 根据数据状态动态切换编辑状态(如特定条件下禁用): ```xml <DataGrid> <DataGrid.RowStyle> <Style TargetType="DataGridRow"> <Style.Triggers> <DataTrigger Binding="{Binding Status}" Value="Approved"> <Setter Property="IsEnabled" Value="False"/> </DataTrigger> </Style.Triggers> </Style> </DataGrid.RowStyle> </DataGrid> ``` #### 3. **通过事件处理程序控制** 在`BeginningEdit`事件中实现条件拦截: ```csharp private void DataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) { if (e.Row.Item is DataItem item && !item.AllowEdit) { e.Cancel = true; // 阻止编辑 } } ``` ```xml <DataGrid BeginningEdit="DataGrid_BeginningEdit" /> ``` #### 4. **自定义行选择器(高级控制)** 创建自定义`DataGridRow`实现细粒度控制: ```csharp public class EditableDataGridRow : DataGridRow { protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { if (e.Property == IsSelectedProperty && IsSelected) { IsEnabled = ((DataItem)Item).IsEditable; } base.OnPropertyChanged(e); } } ``` 在XAML中引用: ```xml <DataGrid> <DataGrid.Resources> <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}"> <Setter Property="local:EditableDataGridRow.IsEditable" Value="{Binding IsEditable}"/> </Style> </DataGrid.Resources> </DataGrid> ``` #### 5. **结合单元格级别的控制** 对特定单元格进行额外控制(引用[4]的扩展): ```xml <DataGridTemplateColumn> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox IsEnabled="{Binding Row.IsEditable, RelativeSource={RelativeSource AncestorType=DataGridRow}}"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> ``` #### 性能优化建议 1. 启用虚拟化提升渲染性能: ```xml <DataGrid EnableRowVirtualization="True" VirtualizingStackPanel.IsVirtualizing="True"/> ``` 2. 简化模板复杂度(引用[2]) 3. 对大数据集使用异步加载(引用[1]) > **提示**:当`IsEnabled="False"`时,整行会呈现灰色禁用状态,提供直观的视觉反馈。若需保持行选择功能但禁用编辑,可改用`IsReadOnly`属性绑定[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值