How do I force showing a tooltip in WPF - c#

I'd like to show a tooltip when I move the mouse.
Here is my code:
private void Grid_MouseMove(object sender, MouseEventArgs e)
{
Grid grid = (Grid) sender;
if (e.GetPosition(grid).X < 100)
grid.ToolTip = e.GetPosition(grid).X.ToString();
else
grid.ToolTip = null;
}
However, the tooltip disappears after I click on the grid.
Is there a way to force showing the tooltip?

var oldTT = SomeElement.ToolTip as ToolTip;
if (oldTT != null) oldTT.IsOpen = false;
SomeElement.ToolTip = new ToolTip
{
Content = "Lalalalala",
IsOpen = true,
};
or
var tt = SomeElement.ToolTip as ToolTip;
if (tt != null) tt.IsOpen = true;

TooltipService.ShowDuration works, but you must set it on the object having the Tooltip, like this:
<Label ToolTipService.ShowDuration="120000" Name="lblTooltip" Content="Shows tooltip">
<Label.ToolTip>
<ToolTip>
<TextBlock>Hi world!</TextBlock>
</ToolTip>
</Label.ToolTip>

Related

ToolTip on ListView SubItem is not shown

I am unable to show tooltips on ListView subitems. Involved implementation is:
ListView sqlView = new ListView() { Dock = DockStyle.Fill, View = View.Details, MultiSelect = true, FullRowSelect = true, HeaderStyle = ColumnHeaderStyle.Nonclickable, GridLines = true };
...
sqlView.ShowItemToolTips = true;
sqlView.MouseMove += sqlView_MouseMove;
...
// filled in foreach, don't worry it's correct here ;)
item.SubItems[columnIndex].Text = "✔";
item.SubItems[columnIndex].Tag = ("via: '" + sqlEntry.Login + "'");
Mouse event handler method:
void sqlView_MouseMove(object sender, MouseEventArgs e)
{
ListView sqlView = ((ListView)sender);
ListViewItem item = sqlView.GetItemAt(e.X, e.Y);
ListViewHitTestInfo info = sqlView.HitTest(e.X, e.Y);
if (item != null && info.SubItem != null && info.SubItem.Tag != null)
{
ToolTip tt = new ToolTip();
//tt.ShowAlways = true; - no effect
//tt.Active = true; - no effect
tt.SetToolTip(sqlView, (String)info.SubItem.Tag);
}
}
Events are firing. Subitems Tags are filled properly. No Tooltip shown. Why?
Thx for help.
Don't create a new ToolTip() each time through. Just create one and reuse it.

How to set tooltip for a ListviewSubItem

I have a ListView control in Details view as that (the view that shows the list as a grid)
mListView.View = View.Details;
mListView.mLVSelectedObject.ShowItemToolTips = true;
ListViewItem listViewItem = mListView.Items.Add(lValue.Name);
listViewItem.ToolTipText = "AAAAAAAAAAAAAAAAA";
The issue is that the tooltip only shows up when the cursors is over the first listview's column but not for the rest o them. I want to know if there's anyway to make it appear "easly" ?
After some research. I've solved the issue this way, but I'm still wondering if there is another way to do that avoiding EventHandlers;
ToolTip mTooltip;
Point mLastPos = new Point(-1, -1);
private void listview_MouseMove(object sender, MouseEventArgs e)
{
ListViewHitTestInfo info = mLV.HitTest(e.X, e.Y);
if (mTooltip == null)
mTooltip = new ToolTip();
if (mLastPos != e.Location)
{
if (info.Item != null && info.SubItem != null)
{
mTooltip.ToolTipTitle = info.Item.Text;
mTooltip.Show(info.SubItem.Text, info.Item.ListView, e.X, e.Y, 20000);
}
else
{
mTooltip.SetToolTip(mLV, string.Empty);
}
}
mLastPos = e.Location;
}

c#: show tooltip on subitem

I have a listview, and in one of the columns (not the first) I want to display an error code.
What I haven't been able to do is get the ToolTip to display. I have
this.lstList.ShowItemToolTips = true;
...
ListViewItem value = lstList.Items.Add(name, name, 0);
...
if (lstList.Columns.Contains(lstColErrorCode))
{
value.SubItems.Add(new ListViewItem.ListViewSubItem(value, errorCode.ToString()));
value.ToolTipText = errorCode.ToString("X");
}
I would like to get the hex value of the code to be shown on the tooltip above the decimal value, but it shows above the name.
I haven't been able to get anything I tried to work (like trying to get the coordinates of the subitem). I would appreciate any suggestion.
this code works for me
ToolTip toolTip1 = new ToolTip();
void initMethod()
{
lstList.MouseMove += new MouseEventHandler(lstList_MouseMove);//mousemove handler
this.lstList.ShowItemToolTips = true;
toolTip1.SetToolTip(lstList,"");// init the tooltip
...
ListViewItem value = lstList.Items.Add(name, name, 0);
...
if (lstList.Columns.Contains(lstColErrorCode))
{
ListViewItem.ListViewSubItem lvs = value.SubItems.Add(new ListViewItem.ListViewSubItem(value, errorCode.ToString()));
lvs.Tag = "mydecimal"; // only the decimal subitem will be tooltiped
}
}
the mousemove event from the listview:
void lstList_MouseMove(object sender, MouseEventArgs e)
{
ListViewItem item = lstList.GetItemAt(e.X, e.Y);
ListViewHitTestInfo info = lstList.HitTest(e.X, e.Y);
if ((item != null) && (info.SubItem != null) && (info.SubItem.Tag!=null) && (info.SubItem.Tag.ToString() == "mydecimal"))
{
toolTip1.SetToolTip(lstList,((decimal)info.SubItem.Text).ToString("X"));
}
else
{
toolTip1.SetToolTip(lstList, "");
}
}

How to make a GridViewColumn readonly/disabled?

I have a reference to a GridViewColumn in my xaml code as RuntimeColumn but I am not able to disable it or set it to readonly programmatically. I will need to do this at runtime without databinding.
I tried:
this.RuntimeColumn.IsEnabled = false;
this.RuntimeColumn.ReadOnly = false;
Any ideas?
You will have to set an EventSetter with Loaded Event, and in your code behind put the following
private void GridViewColumnHeader_Loaded(object sender, RoutedEventArgs e)
{
GridViewColumnHeader columnHeader = sender as GridViewColumnHeader;
Border HeaderBorder = columnHeader.Template.FindName("HeaderBorder", columnHeader) as Border;
if (HeaderBorder != null)
{
HeaderBorder.Background = HeaderBorder.Background;
}
Border HeaderHoverBorder = columnHeader.Template.FindName("HeaderHoverBorder", columnHeader) as Border;
if (HeaderHoverBorder != null)
{
HeaderHoverBorder.BorderBrush = HeaderHoverBorder.BorderBrush;
}
Rectangle UpperHighlight = columnHeader.Template.FindName("UpperHighlight", columnHeader) as Rectangle;
if (UpperHighlight != null)
{
UpperHighlight.Visibility = UpperHighlight.Visibility;
}
Thumb PART_HeaderGripper = columnHeader.Template.FindName("PART_HeaderGripper", columnHeader) as Thumb;
if (PART_HeaderGripper != null)
{
PART_HeaderGripper.Background = PART_HeaderGripper.Background;
PART_HeaderGripper.Cursor = System.Windows.Input.Cursors.Arrow; // override the size curser
}
}

How can I determine coordinates of a Hyperlink in WPF

I have WPF window with a FlowDocument with several hyperlinks in it:
<FlowDocumentScrollViewer>
<FlowDocument TextAlignment="Left" >
<Paragraph>Some text here
<Hyperlink Click="Hyperlink_Click">open form</Hyperlink>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
In the C# code I handle Click event to create and show a new WPF Window:
private void Hyperlink_Click(object sender, RoutedEventArgs e)
{
if (sender is Hyperlink)
{
var wnd = new SomeWindow();
//wnd.Left = ???
//wnd.Top = ???
wnd.Show();
}
}
I need this window to appear next to hyperlink's actual position. So I assume it requires assigning values to the window's Left and Top properties. But I have no idea how to obtain hyperlink position.
You can use ContentStart or ContentEnd to get a TextPointer for the start or end of the hyperlink and then call GetCharacterRect to get the bounding box relative to the FlowDocumentScrollViewer. If you get a reference to the FlowDocumentScrollViewer, you can use PointToScreen to convert it to screen coordinates.
private void Hyperlink_Click(object sender, RoutedEventArgs e)
{
var hyperlink = sender as Hyperlink;
if (hyperlink != null)
{
var rect = hyperlink.ContentStart.GetCharacterRect(
LogicalDirection.Forward);
var viewer = FindAncestor(hyperlink);
if (viewer != null)
{
var screenLocation = viewer.PointToScreen(rect.Location);
var wnd = new Window();
wnd.WindowStartupLocation = WindowStartupLocation.Manual;
wnd.Top = screenLocation.Y;
wnd.Left = screenLocation.X;
wnd.Show();
}
}
}
private static FrameworkElement FindAncestor(object element)
{
while(element is FrameworkContentElement)
{
element = ((FrameworkContentElement)element).Parent;
}
return element as FrameworkElement;
}

Categories