积极答复者
请问怎么在datagrid cell中显示tooltip呢?

问题
答案
-
-----------------------------------------------------------
好人做到底,给你一个完整的例子。
仿造本例子,你可以实现任意外观的DataGrid。
不仅可以做ToolTip,甚至是可以做成中国式的非常复杂的跨列表头的DataGrid(这个是我以前的心病,现在得到完美解决)
事实上,只要你能用xaml能写的,基本都可以用
XamlReader.Load在后台代码中动态生成。不光是什么ToolTip/Coverter之类简单的东西。
-----------------------------------------------------------
例子是用VB.NET做的,如果你用C#请做相应转换。
我熟悉C#,VB.net,但一贯认为如果作为企业应用开发,VB.NET比C#好用多了。
毕竟vb.net的版本已经是10.0了,比较成熟了;而C#才4.0,太年轻了。
当然,大多数人是跟风用C#,不是两种语言都熟悉,如果他对两种都熟悉的话,他会选择VB.net。
0)工程名称:SLDataGridTestSample
1)MainPage.xaml
<UserControl x:Class="SLDataGridTestSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns:datap="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
xmlns:my="clr-namespace:SLDataGridTestSample">
<Grid x:Name="GrdRoot"
Width="400"
Height="200"
Background="White">
<data:DataGrid x:Name="DgrMain"
RowHeight="24"
ColumnHeaderHeight="40">
</data:DataGrid>
</Grid>
</UserControl>
2)MainPage.vb
Partial Public Class MainPage
Inherits UserControlPublic Sub New()
InitializeComponent()
End Sub
Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
DgrMain.AutoGenerateColumns = False
Call AddColumnWithTipAndConverter()Dim TestDataList As New List(Of CTestDataItem)
TestDataList.Add(New CTestDataItem("UserId1", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId2", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId3", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId4", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId5", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId6", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId7", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId8", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId9", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId10", Rnd() * 100))
DgrMain.ItemsSource = TestDataList
End Sub
Private Sub AddColumnWithTipAndConverter()
Dim ColWithTipAndConverter As DataGridTemplateColumn = NothingColWithTipAndConverter = New DataGridTemplateColumn()
ColWithTipAndConverter.Width = New DataGridLength(300)
ColWithTipAndConverter.HeaderStyle = GetColumHeaderStyleWithTip("UserId", "UserId Header ToolTip")
ColWithTipAndConverter.CellTemplate = GetColumnTemplateWithTipAndConverter("UserId")
DgrMain.Columns.Add(ColWithTipAndConverter)ColWithTipAndConverter = New DataGridTemplateColumn()
ColWithTipAndConverter.Width = New DataGridLength(200)
ColWithTipAndConverter.HeaderStyle = GetColumHeaderStyleWithTip("UserScore", "UserScore Header ToolTip")
ColWithTipAndConverter.CellTemplate = GetColumnTemplateWithTipAndConverter("UserScore")
DgrMain.Columns.Add(ColWithTipAndConverter)
End Sub
Private Function GetColumHeaderStyleWithTip(ByVal HeaderStr As String, ByVal HeaderTip As String) As Style
Dim Rlt As Style = Nothing
Dim Xaml As String = "", StTmp As Setter = Nothing
'SLDataGridTestSample --> YourNamespace, YourAssembly
Xaml &= "<DataTemplate"
Xaml &= " xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"""
Xaml &= " xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"""
Xaml &= " xmlns:my=""clr-namespace:SLDataGridTestSample;assembly=SLDataGridTestSample"">" & vbCrLf
Xaml &= " <StackPanel>" & vbCrLf
Xaml &= " <TextBlock Text=""@HeaderStr"" ToolTipService.ToolTip=""@HeaderTip""></TextBlock>" & vbCrLf
Xaml &= " </StackPanel>" & vbCrLf
Xaml &= "</DataTemplate>" & vbCrLf
Xaml = Replace(Xaml, "@HeaderStr", HeaderStr, 1, -1, CompareMethod.Text)
Xaml = Replace(Xaml, "@HeaderTip", HeaderTip, 1, -1, CompareMethod.Text)Rlt = New Style(GetType(System.Windows.Controls.Primitives.DataGridColumnHeader))
StTmp = New Setter()
StTmp.Property = System.Windows.Controls.Primitives.DataGridColumnHeader.ContentTemplateProperty
StTmp.Value = CType(System.Windows.Markup.XamlReader.Load(Xaml), DataTemplate)
Rlt.Setters.Add(StTmp)Return Rlt
End Function
Private Function GetColumnTemplateWithTipAndConverter(ByVal FieldName As String) As DataTemplate
Dim Rlt As DataTemplate = Nothing
Dim Xaml As String = "", Xaml1 As String = ""
Xaml1 = "{Binding Path=@FieldName,ConverterParameter=@FieldName,Converter={StaticResource TestDataConverter},Mode=TwoWay}"
Xaml1 = Replace(Xaml1, "@FieldName", FieldName, 1, -1, CompareMethod.Text)
Xaml &= "<DataTemplate"
Xaml &= " xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"""
Xaml &= " xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"""
Xaml &= " xmlns:my=""clr-namespace:SLDataGridTestSample;assembly=SLDataGridTestSample"">" & vbCrLf
Xaml &= " <StackPanel>" & vbCrLf
Xaml &= " <StackPanel.Resources>" & vbCrLf
Xaml &= " <my:CTestDataConverter x:Key=""TestDataConverter""></my:CTestDataConverter>" & vbCrLf
Xaml &= " </StackPanel.Resources>" & vbCrLf
Xaml &= " <TextBlock VerticalAlignment=""Center"" Text=""@Xaml1"" ToolTipService.ToolTip=""@Xaml1""></TextBlock>" & vbCrLf
Xaml &= " </StackPanel>" & vbCrLf
Xaml &= "</DataTemplate>" & vbCrLf
Xaml = Replace(Xaml, "@Xaml1", Xaml1, 1, -1, CompareMethod.Text)
Rlt = CType(System.Windows.Markup.XamlReader.Load(Xaml), DataTemplate)
Return Rlt
End Function
End ClassPublic Class CTestDataItem
Implements System.ComponentModel.INotifyPropertyChanged
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) _
Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(ByVal PropertyName As String)
RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(PropertyName))
End Sub
Dim _UserId As String
Public Sub New()
UserId = "" : UserScore = 0
End Sub
Public Sub New(ByVal TheUserId As String, ByVal TheUserScore As Double)
UserId = TheUserId : UserScore = TheUserScore
End Sub
Public Property UserId() As String
Get
Return _UserId
End Get
Set(ByVal value As String)
_UserId = value : NotifyPropertyChanged("UserId")
End Set
End Property
Dim _UserScore As Double
Public Property UserScore() As Double
Get
Return _UserScore
End Get
Set(ByVal value As Double)
_UserScore = value : NotifyPropertyChanged("UserScore")
End Set
End Property
End ClassPublic Class CTestDataConverter
Implements System.Windows.Data.IValueConverter
Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
Dim Rlt As Object = value
If value IsNot Nothing Then
Select Case UCase(parameter & "")
Case UCase("UserScore") : Rlt = Format(CType(value, Double), "#0.00")
End Select
End If
Return Rlt
End Function
Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
Dim Rlt As Object = value
Return Rlt
End Function
End Class- 已建议为答案 TFSoft 2009年11月4日 6:14
- 已标记为答案 Allen Chen - MSFT 2009年11月9日 2:45
2009年11月4日 4:52
全部回复
-
通过在后台代码中创建
Dim Xaml As String
Xaml &="<DataTemplate>"
Xaml &= <TextBlock ToopTipService.ToolTip=""Your ToolTip"" />
Xaml &="</DataTemplate>"
Dim TplTipCell As DataTemplate = XamlReader.LoadXaml(XamlStr) '根据字符串生成对象的那个方法的名字记得不是很清除,你自己查一下
YourDataGrid.Columns(???).CellTemplate = TplTipCell
..........................
没写全,大致就是这样,具体你自己完成
总之,完全没问题创建2009年11月2日 17:59 -
-----------------------------------------------------------
好人做到底,给你一个完整的例子。
仿造本例子,你可以实现任意外观的DataGrid。
不仅可以做ToolTip,甚至是可以做成中国式的非常复杂的跨列表头的DataGrid(这个是我以前的心病,现在得到完美解决)
事实上,只要你能用xaml能写的,基本都可以用
XamlReader.Load在后台代码中动态生成。不光是什么ToolTip/Coverter之类简单的东西。
-----------------------------------------------------------
例子是用VB.NET做的,如果你用C#请做相应转换。
我熟悉C#,VB.net,但一贯认为如果作为企业应用开发,VB.NET比C#好用多了。
毕竟vb.net的版本已经是10.0了,比较成熟了;而C#才4.0,太年轻了。
当然,大多数人是跟风用C#,不是两种语言都熟悉,如果他对两种都熟悉的话,他会选择VB.net。
0)工程名称:SLDataGridTestSample
1)MainPage.xaml
<UserControl x:Class="SLDataGridTestSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns:datap="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
xmlns:my="clr-namespace:SLDataGridTestSample">
<Grid x:Name="GrdRoot"
Width="400"
Height="200"
Background="White">
<data:DataGrid x:Name="DgrMain"
RowHeight="24"
ColumnHeaderHeight="40">
</data:DataGrid>
</Grid>
</UserControl>
2)MainPage.vb
Partial Public Class MainPage
Inherits UserControlPublic Sub New()
InitializeComponent()
End Sub
Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
DgrMain.AutoGenerateColumns = False
Call AddColumnWithTipAndConverter()Dim TestDataList As New List(Of CTestDataItem)
TestDataList.Add(New CTestDataItem("UserId1", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId2", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId3", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId4", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId5", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId6", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId7", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId8", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId9", Rnd() * 100))
TestDataList.Add(New CTestDataItem("UserId10", Rnd() * 100))
DgrMain.ItemsSource = TestDataList
End Sub
Private Sub AddColumnWithTipAndConverter()
Dim ColWithTipAndConverter As DataGridTemplateColumn = NothingColWithTipAndConverter = New DataGridTemplateColumn()
ColWithTipAndConverter.Width = New DataGridLength(300)
ColWithTipAndConverter.HeaderStyle = GetColumHeaderStyleWithTip("UserId", "UserId Header ToolTip")
ColWithTipAndConverter.CellTemplate = GetColumnTemplateWithTipAndConverter("UserId")
DgrMain.Columns.Add(ColWithTipAndConverter)ColWithTipAndConverter = New DataGridTemplateColumn()
ColWithTipAndConverter.Width = New DataGridLength(200)
ColWithTipAndConverter.HeaderStyle = GetColumHeaderStyleWithTip("UserScore", "UserScore Header ToolTip")
ColWithTipAndConverter.CellTemplate = GetColumnTemplateWithTipAndConverter("UserScore")
DgrMain.Columns.Add(ColWithTipAndConverter)
End Sub
Private Function GetColumHeaderStyleWithTip(ByVal HeaderStr As String, ByVal HeaderTip As String) As Style
Dim Rlt As Style = Nothing
Dim Xaml As String = "", StTmp As Setter = Nothing
'SLDataGridTestSample --> YourNamespace, YourAssembly
Xaml &= "<DataTemplate"
Xaml &= " xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"""
Xaml &= " xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"""
Xaml &= " xmlns:my=""clr-namespace:SLDataGridTestSample;assembly=SLDataGridTestSample"">" & vbCrLf
Xaml &= " <StackPanel>" & vbCrLf
Xaml &= " <TextBlock Text=""@HeaderStr"" ToolTipService.ToolTip=""@HeaderTip""></TextBlock>" & vbCrLf
Xaml &= " </StackPanel>" & vbCrLf
Xaml &= "</DataTemplate>" & vbCrLf
Xaml = Replace(Xaml, "@HeaderStr", HeaderStr, 1, -1, CompareMethod.Text)
Xaml = Replace(Xaml, "@HeaderTip", HeaderTip, 1, -1, CompareMethod.Text)Rlt = New Style(GetType(System.Windows.Controls.Primitives.DataGridColumnHeader))
StTmp = New Setter()
StTmp.Property = System.Windows.Controls.Primitives.DataGridColumnHeader.ContentTemplateProperty
StTmp.Value = CType(System.Windows.Markup.XamlReader.Load(Xaml), DataTemplate)
Rlt.Setters.Add(StTmp)Return Rlt
End Function
Private Function GetColumnTemplateWithTipAndConverter(ByVal FieldName As String) As DataTemplate
Dim Rlt As DataTemplate = Nothing
Dim Xaml As String = "", Xaml1 As String = ""
Xaml1 = "{Binding Path=@FieldName,ConverterParameter=@FieldName,Converter={StaticResource TestDataConverter},Mode=TwoWay}"
Xaml1 = Replace(Xaml1, "@FieldName", FieldName, 1, -1, CompareMethod.Text)
Xaml &= "<DataTemplate"
Xaml &= " xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"""
Xaml &= " xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"""
Xaml &= " xmlns:my=""clr-namespace:SLDataGridTestSample;assembly=SLDataGridTestSample"">" & vbCrLf
Xaml &= " <StackPanel>" & vbCrLf
Xaml &= " <StackPanel.Resources>" & vbCrLf
Xaml &= " <my:CTestDataConverter x:Key=""TestDataConverter""></my:CTestDataConverter>" & vbCrLf
Xaml &= " </StackPanel.Resources>" & vbCrLf
Xaml &= " <TextBlock VerticalAlignment=""Center"" Text=""@Xaml1"" ToolTipService.ToolTip=""@Xaml1""></TextBlock>" & vbCrLf
Xaml &= " </StackPanel>" & vbCrLf
Xaml &= "</DataTemplate>" & vbCrLf
Xaml = Replace(Xaml, "@Xaml1", Xaml1, 1, -1, CompareMethod.Text)
Rlt = CType(System.Windows.Markup.XamlReader.Load(Xaml), DataTemplate)
Return Rlt
End Function
End ClassPublic Class CTestDataItem
Implements System.ComponentModel.INotifyPropertyChanged
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) _
Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(ByVal PropertyName As String)
RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(PropertyName))
End Sub
Dim _UserId As String
Public Sub New()
UserId = "" : UserScore = 0
End Sub
Public Sub New(ByVal TheUserId As String, ByVal TheUserScore As Double)
UserId = TheUserId : UserScore = TheUserScore
End Sub
Public Property UserId() As String
Get
Return _UserId
End Get
Set(ByVal value As String)
_UserId = value : NotifyPropertyChanged("UserId")
End Set
End Property
Dim _UserScore As Double
Public Property UserScore() As Double
Get
Return _UserScore
End Get
Set(ByVal value As Double)
_UserScore = value : NotifyPropertyChanged("UserScore")
End Set
End Property
End ClassPublic Class CTestDataConverter
Implements System.Windows.Data.IValueConverter
Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
Dim Rlt As Object = value
If value IsNot Nothing Then
Select Case UCase(parameter & "")
Case UCase("UserScore") : Rlt = Format(CType(value, Double), "#0.00")
End Select
End If
Return Rlt
End Function
Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
Dim Rlt As Object = value
Return Rlt
End Function
End Class- 已建议为答案 TFSoft 2009年11月4日 6:14
- 已标记为答案 Allen Chen - MSFT 2009年11月9日 2:45
2009年11月4日 4:52