Sql server 具有特殊属性的DataGridView自定义列
我似乎找不到有效的解决办法 我有一个基于DataGridViewTextboxColumn的自定义datagridview单元格。我用VB2005来做这个 我正在尝试实现一个设计时属性,可以用来存储列中的单元格使用的SQL语句。每行的查找相同,但返回的值不同 我有一个版本要求我在CellFormatting和RowsAdded事件期间设置语句,但我希望这样做,我所要做的就是提供一个SQL语句(即从JobList中选择JobName,其中JobNo={0})作为column类中的属性。我想绑定单元格并使用它得到的值作为语句的替换值。我无法使SQL语句属性保持不变(对吗 我的部分问题是,我不确定该属性应该放在自定义列还是自定义单元格定义中。我一直在尝试将属性添加到列中,这似乎是合乎逻辑的,因为我希望在每次触发单元格格式事件时,如果单元格不必设置语句值,则每个实例都使用相同的值 我找到并尝试了以下属性:Sql server 具有特殊属性的DataGridView自定义列,sql-server,vb.net,datagridview,custom-controls,Sql Server,Vb.net,Datagridview,Custom Controls,我似乎找不到有效的解决办法 我有一个基于DataGridViewTextboxColumn的自定义datagridview单元格。我用VB2005来做这个 我正在尝试实现一个设计时属性,可以用来存储列中的单元格使用的SQL语句。每行的查找相同,但返回的值不同 我有一个版本要求我在CellFormatting和RowsAdded事件期间设置语句,但我希望这样做,我所要做的就是提供一个SQL语句(即从JobList中选择JobName,其中JobNo={0})作为column类中的属性。我想绑定单元
<Browsable(True), _
EditorBrowsable(EditorBrowsableState.Always), _
Category("Data"), _
Description("The SQL Query to use for lookup. Make sure it will work with string.format"), _
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
Public Property ScalarSQLStatement() As String
End Property
并将其添加到表单初始化中:
colHaulID2.ScalarSQLStatement = "Select CompanyName From HaulCompany Where HaulID = {0}"
该列是数据绑定的,并在那里获取其查找值。它工作正常,但不是我正在寻找的解决方案
我正在尝试重写单元格/列,以便在设计时使用列编辑器将SQL语句添加到列中,并依靠数据绑定值提供查找键
在我看来,阻止我实现目标的唯一一件事是,在设计时关闭列编辑器后,让控件保存它的SQL语句。或者在我重新打开列编辑器时防止它被清除。我不确定发生了什么。但我相信有一个解决办法。我在持久化方面做了一些尝试,包括我发现的一个类似VB6的属性包示例。我忽略将属性保存到磁盘。似乎应该有一种方法让应用程序处理此任务。到目前为止,我什么都没用
结束编辑
任何帮助都将不胜感激
谢谢
Marshall双击演示第一列中的单元格
Public Class Form1
Sub New()
' This call is required by the designer.'
InitializeComponent()
' Add any initialization after the InitializeComponent() call.'
Dim dtb As New DataTable
dtb.Columns.Add("C1")
dtb.Columns.Add("C2")
dtb.Columns.Add("C3")
dtb.Rows.Add("1", "2", "3")
dtb.Rows.Add("2", "3", "4")
dtb.Rows.Add("3", "4", "5")
dtb.Rows.Add("4", "5", "6")
DataGridView1.DataSource = dtb
DataGridView1.Columns(0).Tag = "Select JobName From JobList where JobNo = {0}"
End Sub
Private Sub DataGridView1_CellMouseDoubleClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDoubleClick
Dim strSql As String = String.Format(DataGridView1.Columns(e.ColumnIndex).Tag.ToString, DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString)
MsgBox(strSql)
End Sub
End Class
我找到了我一直在寻找的解决方案 我需要重写列(而不是单元格)中的Clone方法,并确保在运行时将属性传递给单元格。下面我将发布我的最终解决方案 (我在堆栈溢出上找到了解决方案。)
导入System.ComponentModel
导入System.ComponentModel.Design
_
公共类DataGridViewScalarValueTextboxColumn
继承DataGridViewTextBoxColumn
公共分新()
Me.CellTemplate=新建DataGridViewScalarValueTextboxCell()
端接头
“字段…”
Private _scalarSQLStatement作为String=String.Empty
_
公共属性ScalarSQLStatementCol()作为字符串
得到
Return\u scalarSQLStatement
结束
设置(ByVal值作为字符串)
_scalarSQLStatement=值
端集
端属性
公共重写函数Clone()作为对象
将myClone设置为DataGridViewScalarValueTextboxColumn=CType(MyBase.Clone,DataGridViewScalarValueTextboxColumn)
myClone.ScalarSQLStatementCol=ScalarSQLStatementCol
返回myClone
端函数
末级
公共类DataGridViewScalarValueTextboxCell
继承DataGridViewTextBoxCell
Private _returnvalueas String=String.Empty
Private _LookupValue作为对象
作为对象的公共属性LookupValue()
得到
返回_LookupValue
结束
设置(ByVal值作为对象)
_LookupValue=值
端集
端属性
公共分新()
Me.\u LookupValue=无
端接头
公共重写函数Clone()作为对象
'现在可能不需要方法'
将单元格设置为DataGridViewScalarValueTextboxCell=CType(MyBase.Clone()_
DataGridViewScalarValueTextboxCell)
返回单元
端函数
受保护的覆盖函数GetFormattedValue(ByVal值作为对象_
ByVal行索引为整数_
ByRef cellStyle作为DataGridViewCellStyle_
ByVal valueTypeConverter作为类型转换器_
ByVal formattedValueTypeConverter作为类型转换器_
ByVal上下文作为DataGridViewDataErrorContexts)作为对象
如果_LookupValue值,则
_LookupValue=值
GetReturnValueFromLookupValue()
如果结束
Return MyBase.GetFormattedValue(_ReturnValue,rowIndex,cellStyle_
valueTypeConverter,格式化的valueTypeConverter,上下文)
端函数
受保护的覆盖子绘制(ByVal图形作为图形_
ByVal剪贴簿为矩形_
ByVal单元格边界为矩形_
ByVal行索引为整数_
ByVal cellState作为DataGridViewElementState_
ByVal值作为对象_
ByVal formattedValue作为对象_
ByVal errorText作为字符串_
ByVal cellStyle作为DataGridViewCellStyle_
ByVal advancedBorderStyle作为DataGridViewAdvancedBorderStyle_
ByVal paintParts作为DataGridViewPaintParts)
如果值不是空,那么_
(值的类型是String,也不是String.IsNullOrEmpty(值))或_
(TypeOf值是整数,也是整数。TryParse(value,Nothing))或_
Private Sub dgvCustomCellTypes_CellFormatting(ByVal sender As Object, ByVal e As .DataGridViewCellFormattingEventArgs) Handles dgvCustomCellTypes.CellFormatting
If e.ColumnIndex = colHaulID2.Index Then
Dim dgvr As DataGridViewRow = CType(sender, DataGridView).Rows(e.RowIndex)
Dim HaulCell As DataGridViewScalarValue2TextboxCell = CType(dgvr.Cells(colHaulID2.Index), DataGridViewScalarValue2TextboxCell)
HaulCell.ScalarStatement = colHaulID2.ScalarSQLStatement
End If
End Sub
Private Sub dgvCustomCellTypes_RowsAdded(ByVal sender As Object, ByVal e As DataGridViewRowsAddedEventArgs) Handles dgvCustomCellTypes.RowsAdded
For i As Integer = e.RowIndex To e.RowCount - 1
Dim dgvr As DataGridViewRow = CType(sender, DataGridView).Rows(i)
Dim HaulCell As DataGridViewScalarValue2TextboxCell = CType(dgvr.Cells(colHaulID2.Index), DataGridViewScalarValue2TextboxCell)
HaulCell.ScalarStatement = colHaulID2.ScalarSQLStatement
Next
End Sub
colHaulID2.ScalarSQLStatement = "Select CompanyName From HaulCompany Where HaulID = {0}"
Public Class Form1
Sub New()
' This call is required by the designer.'
InitializeComponent()
' Add any initialization after the InitializeComponent() call.'
Dim dtb As New DataTable
dtb.Columns.Add("C1")
dtb.Columns.Add("C2")
dtb.Columns.Add("C3")
dtb.Rows.Add("1", "2", "3")
dtb.Rows.Add("2", "3", "4")
dtb.Rows.Add("3", "4", "5")
dtb.Rows.Add("4", "5", "6")
DataGridView1.DataSource = dtb
DataGridView1.Columns(0).Tag = "Select JobName From JobList where JobNo = {0}"
End Sub
Private Sub DataGridView1_CellMouseDoubleClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDoubleClick
Dim strSql As String = String.Format(DataGridView1.Columns(e.ColumnIndex).Tag.ToString, DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString)
MsgBox(strSql)
End Sub
End Class
Imports System.ComponentModel
Imports System.ComponentModel.Design
<Serializable()> _
Public Class DataGridViewScalarValueTextboxColumn
Inherits DataGridViewTextBoxColumn
Public Sub New()
Me.CellTemplate = New DataGridViewScalarValueTextboxCell()
End Sub
' Fields...'
Private _scalarSQLStatement As String = String.Empty
<Browsable(True), _
Category("Data"), _
Description("The SQL Query to use for lookup. Must work with the string.format function if lookup value is used."), _
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
Public Property ScalarSQLStatementCol() As String
Get
Return _scalarSQLStatement
End Get
Set(ByVal Value As String)
_scalarSQLStatement = Value
End Set
End Property
Public Overrides Function Clone() As Object
Dim myClone As DataGridViewScalarValueTextboxColumn = CType(MyBase.Clone, DataGridViewScalarValueTextboxColumn)
myClone.ScalarSQLStatementCol = ScalarSQLStatementCol
Return myClone
End Function
End Class
Public Class DataGridViewScalarValueTextboxCell
Inherits DataGridViewTextBoxCell
Private _ReturnValue As String = String.Empty
Private _LookupValue As Object
Public Property LookupValue() As Object
Get
Return _LookupValue
End Get
Set(ByVal value As Object)
_LookupValue = value
End Set
End Property
Public Sub New()
Me._LookupValue = Nothing
End Sub
Public Overrides Function Clone() As Object
'Method may not be needed now'
Dim Cell As DataGridViewScalarValueTextboxCell = CType(MyBase.Clone(), _
DataGridViewScalarValueTextboxCell)
Return Cell
End Function
Protected Overrides Function GetFormattedValue(ByVal value As Object, _
ByVal rowIndex As Integer, _
ByRef cellStyle As DataGridViewCellStyle, _
ByVal valueTypeConverter As TypeConverter, _
ByVal formattedValueTypeConverter As TypeConverter, _
ByVal context As DataGridViewDataErrorContexts) As Object
If _LookupValue <> value Then
_LookupValue = value
GetReturnValueFromLookupValue()
End If
Return MyBase.GetFormattedValue(_ReturnValue, rowIndex, cellStyle, _
valueTypeConverter, formattedValueTypeConverter, context)
End Function
Protected Overrides Sub Paint(ByVal graphics As Graphics, _
ByVal clipBounds As Rectangle, _
ByVal cellBounds As Rectangle, _
ByVal rowIndex As Integer, _
ByVal cellState As DataGridViewElementStates, _
ByVal value As Object, _
ByVal formattedValue As Object, _
ByVal errorText As String, _
ByVal cellStyle As DataGridViewCellStyle, _
ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, _
ByVal paintParts As DataGridViewPaintParts)
If value IsNot Nothing AndAlso _
(TypeOf value Is String AndAlso Not String.IsNullOrEmpty(value)) OrElse _
(TypeOf value Is Integer AndAlso Integer.TryParse(value, Nothing)) OrElse _
(TypeOf value Is Decimal AndAlso Decimal.TryParse(value, 0)) OrElse _
(TypeOf value Is Date) AndAlso IsDate(value) Then
_LookupValue = value
GetReturnValueFromLookupValue()
Else
_ReturnValue = String.Empty
End If
MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, _
_ReturnValue, errorText, cellStyle, advancedBorderStyle, paintParts)
End Sub
Private Sub GetReturnValueFromLookupValue()
If _LookupValue Is Nothing _
Or (OwningColumn Is Nothing _
OrElse CType(Me.OwningColumn, DataGridViewScalarValue2TextboxColumn).ScalarSQLStatementCol.Length = 0) Then
_ReturnValue = Nothing
Return
End If
Using conn As New SqlClient.SqlConnection(ConnUtils.MyGCPTableConnectionString)
conn.Open()
Dim cmd As SqlClient.SqlCommand = conn.CreateCommand
With cmd
.CommandText = String.Format(CType(Me.OwningColumn, DataGridViewScalarValue2TextboxColumn).ScalarSQLStatementCol, _LookupValue)
.CommandType = CommandType.Text
Dim objResult = .ExecuteScalar
If objResult IsNot Nothing Then
_ReturnValue = objResult
End If
End With
conn.Close()
End Using
End Sub
Public Overloads Property Value() As Object
Get
Return _ReturnValue
End Get
Set(ByVal value)
If TypeOf value Is Integer AndAlso value > 0 Then
If _LookupValue <> value Then
_LookupValue = value
GetReturnValueFromLookupValue()
End If
End If
End Set
End Property
End Class