I have a requirement to show a link at the end of each row, allowing the user to click on that link to execute some other action. I created a Template and it works great - see below.
As a secondary requirement, we would like all links to be invisible or collapsed - a link should only be visible when the user hovers its corresponding row.
Is there anyway to make one link appear as the user hovers overs over its corresponding row?
<Style x:Key="MyLinkStyle" TargetType="{x:Type igDP:CellValuePresenter}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}"> <DockPanel> <!-- Give the left edge of the cell a vertical line. --> <Border DockPanel.Dock="Left" BorderBrush="#FFEEEEEE" BorderThickness="1,0,0,0" /> <StackPanel> <TextBlock x:Name="tbLink" Text="{Binding Path=DataItem.MyCount}" Tag="{Binding Path=DataItem.MyID}" ToolTip="{Binding Path=DataItem.MyTooltip}" FontSize="11" TextAlignment="Center" Cursor="Hand" ForceCursor="False" Foreground="#FF4731BD" Width="Auto" FontFamily="Arial" PreviewMouseLeftButtonDown="tbLink_PreviewMouseLeftButtonDown"> <TextBlock.TextDecorations> <TextDecoration Location="Underline"/> </TextBlock.TextDecorations> </TextBlock> </StackPanel> </DockPanel> </ControlTemplate> </Setter.Value> </Setter> </Style>
Notes on the template above:
I hooked up an event handler (tbLink_PreviewMouseLeftButtonDown) and I can access DataItem.MyID from within the handler without problems.
Since you are using the approach Aaron suggested, you should create a setter for the visibility for the CellValuePresenter, not the textblock, as you need the whole Cell to be hidden or collapsed like this
<Style x:Key="MyLinkStyle" TargetType="{x:Type igDP:CellValuePresenter}">
<Setter Property="Visibility" Value="Hidden" /> // or Value="Collapsed"
...
</Style>
Alex.
Playing around, I found the answer - see the line in bold below:
<Style x:Key="MyLinkStyle" TargetType="{x:Type igDP:CellValuePresenter}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}"> <DockPanel> <!-- Give the left edge of the cell a vertical line. --> <Border DockPanel.Dock="Left" BorderBrush="#FFEEEEEE" BorderThickness="1,0,0,0" /> <StackPanel> <TextBlock x:Name="tbLink" Text="{Binding Path=DataItem.MyCount}" Tag="{Binding Path=DataItem.MyID}" ToolTip="{Binding Path=DataItem.MyTooltip}" FontSize="11" TextAlignment="Center" Cursor="Hand" ForceCursor="False" Foreground="#FF4731BD" Width="Auto" FontFamily="Arial" PreviewMouseLeftButtonDown="tbLink_PreviewMouseLeftButtonDown"> <TextBlock.TextDecorations> <TextDecoration Location="Underline"/> </TextBlock.TextDecorations> </TextBlock> </StackPanel> </DockPanel> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="Visibility" Value="Hidden" /> </Style>
One last question: I'd like all the links to start out hidden and only show up as the user hovers over each row. With my current style, the links are all visible until I hover over them, at which point it works as requested.
I tried setting the visibility of the TextBlock to "Hidden" in the style below, but that didn't work. I need to set the CellValuePresenter's visibility to hidden by default - what do I need to change in the style below to do that?
Hi Aaron,
That worked, thanks! For anyone trying this out, here's some sample code:
Sub New() EventManager.RegisterClassHandler(GetType(DataRecordCellArea), DataRecordCellArea.MouseEnterEvent, New MouseEventHandler(AddressOf OnDataRecordCellAreaMouseEnter)) EventManager.RegisterClassHandler(GetType(DataRecordCellArea), DataRecordCellArea.MouseLeaveEvent, New MouseEventHandler(AddressOf OnDataRecordCellAreaMouseLeave)) ' This call is required by the Windows Form Designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. End Sub Private Sub OnDataRecordCellAreaMouseEnter(ByVal sender As Object, ByVal e As MouseEventArgs) Dim oXamDataGrid As XamDataGrid Dim oDataRecordCellArea As DataRecordCellArea Try oXamDataGrid = TryCast(TryCast(sender, DataRecordCellArea).DataPresenter, XamDataGrid) If oXamDataGrid IsNot Nothing AndAlso UCase(oXamDataGrid.Name) = "MYNAMEOFXAMDATAGRIDIFMULTIPLE" Then oDataRecordCellArea = TryCast(sender, DataRecordCellArea) If oDataRecordCellArea IsNot Nothing Then CellValuePresenter.FromCell(oDataRecordCellArea.Record.Cells("MYFIELDNAME")).Visibility = Visibility.Visible End If Catch ex As Exception End Try End Sub Private Sub OnDataRecordCellAreaMouseLeave(ByVal sender As Object, ByVal e As MouseEventArgs) Dim oXamDataGrid As XamDataGrid Dim oDataRecordCellArea As DataRecordCellArea Try oXamDataGrid = TryCast(TryCast(sender, DataRecordCellArea).DataPresenter, XamDataGrid) If oXamDataGrid IsNot Nothing AndAlso UCase(oXamDataGrid.Name) = "MYNAMEOFXAMDATAGRIDIFMULTIPLE" Then oDataRecordCellArea = TryCast(sender, DataRecordCellArea) If oDataRecordCellArea IsNot Nothing Then CellValuePresenter.FromCell(oDataRecordCellArea.Record.Cells("MYFIELDNAME")).Visibility = Visibility.Hidden End If Catch ex As Exception End Try End Sub
Hello ehuna,
You may be able to substitute the DataRecordCellArea Mouse events for the CellValuePresenter events. Then you can get the CellValuePresenter for the specific row that you hover over. In your mouse events, you can retrieve the appropriate CellValuePresenter with the following code:
DataRecordCellArea dr = new DataRecordCellArea(); CellValuePresenter.FromCell(dr.Record.Cells["FieldName"]).Visibility = Visibility.Visible;
I hope that helps