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;
}
Related
This question builds off of this question. What I am doing is attempting to add a DateTimePicker control to a contextmenustrip using ToolStripControlHost. What is odd is the first time I select it in the contextmenu it shows at the location (0,0)
When I hover back to the option again, it displays at the right location.
I can't find where its setting the location. I've tried setting the location of the control being added but does nothing.
public SampleProgram()
{
IntializeComponent();
DateTimePicker sampleDatePicker = new DateTimePicker();
sampleDatePicker.TextChanged += new EventHandler(dateTimePicker_OnTextChange);
sampleDatePicker.Format = DateTimePickerFormat.Short;
datagridview1.Controls.Add(sampleDatePicker);
}
private void datagridview1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex != -1 && e.RowIndex != -1 && e.Button == MouseButtons.Right)
{
datagridview1.ContextMenuStrip = new ContextMenuStrip();
datagirdview1.ContextMenuStrip.Items.Clear();
Get_Alphabetical_User_Groups(datagridview1.ContextMenuStrip, SampleContextMenu_Action);
datagridview1.ContextMenuStrip.Items.Add(new ToolStripSeparator());
GetStatusList(datagridview1.ContextMenuStrip, false, SampleContextMenu_Action);
datagridview1.ContextMenuStrip.Items.Add(new ToolStripSeparator());
GetDatePicker(datagridview1.ContextMenuStrip, SampleContextMenu_Action);
datagridview1.ContextMenuStrip.Items.Add("Copy Cell Data", Resources.blank, SampleContextMenu_Action);
datagridview1.ContextMenuStrip.Show(Cursor.Position.X, Cursor.Position.Y);
}
}
private void GetDatePicker(ContextMenuStrip dateMenu, EventHandler MenuOption_Click_Handler)
{
Point mouseloc = Cursor.Position;
sampleDatePicker.Location = mouseloc;
var datePicker = new ToolStripControlHost(sampleDatePicker);
datagridview1.ContextMenuStrip.Items.Add(new ToolStripMenuItem("Set Followup Date to", Resources.calendar_edit, datePicker));
}
Any help is much appreciated!
Don't add the control to the DataGridView's Control collection. It doesn't belong there:
// datagridview1.Controls.Add(sampleDatePicker);
In a WinForms app, we can re-name ListView Items by clicking them twice. Can we somehow rename Group Headers the same way? Is there a way to enable this?
I guess it is doable after all, albeit not by simply enabling a property..
Note: The code below assumes that the ListView is in Details mode!
The trick to tell a Group from emtpy space is to test the right side of the ListView. Another trick is to wait a little: The click will select the Group Items. Only after that can we proceed..
Here is an example that overlays the Group with a TextBox:
// class variable to test if have been hit twice in a row
ListViewGroup lastHitGroup = null;
private void listView1_MouseDown(object sender, MouseEventArgs e)
{
// check left side to see if we are at the empty space
ListViewItem lvi = listView1.GetItemAt(4, e.Y);
// yes, no action! reset group
if (lvi != null) { lastHitGroup = null; return; }
// get the height of an Item
int ih = listView1.GetItemRect(0).Height;
// to get the group we need to check the next item:
ListViewItem lviNext = listView1.GetItemAt(4, e.Y + ih);
// no next item, maybe the group is emtpy, no action
if (lviNext == null) return;
// this is our group
ListViewGroup editedGroup = lviNext.Group;
// is this the 2nd time?
if (lastHitGroup != editedGroup) {lastHitGroup = editedGroup; return;}
// we overlay a TextBox
TextBox tb = new TextBox();
tb.Parent = listView1;
// set width as you like!
tb.Height = ih;
// we position it over the group header and show it
tb.Location = new Point(0, lviNext.Position.Y - ih - 4);
tb.Show();
// we need two events to quit editing
tb.KeyPress += (ss, ee) =>
{
if (ee.KeyChar == (char)13) // success
{
if (editedGroup != null && tb.Text.Length > 0)
editedGroup.Header = tb.Text;
tb.Hide();
ee.Handled = true;
}
else if (ee.KeyChar == (char)27) // abort
{
tb.Text = ""; tb.Hide(); ee.Handled = true;
}
};
tb.LostFocus += (ss, ee) => // more success
{
if (editedGroup != null && tb.Text.Length > 0)
editedGroup.Header = tb.Text;
tb.Hide();
};
// we need to wait a little until the group items have been selected
Timer lvTimer = new Timer();
lvTimer.Interval = 333; // could take longer for a huge number of items!
lvTimer.Tick += (ss,ee) => { tb.Focus(); lvTimer.Stop();};
lvTimer.Start();
}
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.
I am Silverlight developer and coding in C# to select an item from a list and display the selected item in the textBlock nearby.
My code to do so is:
ListBox lines = new ListBox();
TextBlock txtblkShowSelectedValue = new TextBlock();
ScrollViewer scrollViewer = new ScrollViewer();
scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
lines.ItemsSource = param.Component.Attributes.Items;
Grid.SetColumn(lines, 1);
Grid.SetRow(lines, LoopCount);
childGrid.Children.Add(lines);
lines.SelectedIndex = 0;
lines.SelectedItem = param.Component.Attributes.Items;
The problem is how to select a value and how to display it in textblock "txtblkShowSelectedValue " ? because I cannot declare textblock and List variable globally because of current condition if I use selectionChange event
EDIT: The current scenario is :(lines (List) is in different function so it's not in scope of List_SelectionChanged() function)
private static Grid GenerateList(Parameter param, int LoopCount, Grid g)
{
Grid childGrid = new Grid();
ColumnDefinition colDef1 = new ColumnDefinition();
ColumnDefinition colDef2 = new ColumnDefinition();
ColumnDefinition colDef3 = new ColumnDefinition();
childGrid.ColumnDefinitions.Add(colDef1);
childGrid.ColumnDefinitions.Add(colDef2);
childGrid.ColumnDefinitions.Add(colDef3);
TextBlock txtblk1ShowStatus = new TextBlock();
TextBlock txtblkLabel = new TextBlock();
ListBox lines = new ListBox();
ScrollViewer scrollViewer = new ScrollViewer();
scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
lines.ItemsSource = param.Component.Attributes.Items;
Grid.SetColumn(lines, 1);
Grid.SetRow(lines, LoopCount);
childGrid.Children.Add(lines);
lines.SelectedIndex = 0;
lines.SelectedItem = param.Component.Attributes.Items;
lines.SelectionChanged += new SelectionChangedEventHandler(List_SelectionChanged);
lines.SelectedIndex = lines.Items.Count - 1;
g.Children.Add(childGrid);
return (g);
}
static void List_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
MessageBox.Show("clist _SelectionChanged1");
TextBlock txtblk1ShowStatus = new TextBlock();
txtblk1ShowStatus.Text = lines[(sender as ListBox).SelectedIndex];
}
This could be streamlined, but should work as a quick 'n dirty example of one way to solve the problem...
void lb_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Grid g = null;
ListBox lb = sender as ListBox;
if (lb != null && lb.SelectedIndex >= 0)
{
// Find the top-level grid
var parent = VisualTreeHelper.GetParent(lb);
while (parent != null)
{
if (parent.GetType() == typeof(Grid))
{
if ((parent as Grid).Name.Equals("LayoutRoot"))
{
g = (Grid)parent;
break;
}
}
parent = VisualTreeHelper.GetParent(parent);
}
// Found the LayoutRoot, find the textblock
if (g != null)
{
for (int i = 0; i < g.Children.Count; i++)
{
var child = VisualTreeHelper.GetChild(g, i);
if (child is TextBlock)
{
(child as TextBlock).Text = (string)lb.SelectedItem;
break;
}
}
}
}
}
You could also name your textblock and search for that (as I did for "LayoutRoot").
Obviously, this code assumes the textblock is a child of the top-level Grid. Implementing a recursive search wouldn't be difficult.
lines.SelectionChanged+=new System.EventHandler(this.UpdateTextBlock); // add selectionchanged even for your listbox;
private void UpdateTextBlock(object sender, SelectionChangedEventArgs e)
{
txtblkShowSelectedValue.Text=this.lines[(sender as Listbox).SelectedIndex].ToString(); // just edit the content of your texblock
}
EDIT : thank you, and sorry to be late :-)
try this :
add parameter for the function, as this :
lines.SelectionChanged += new SelectionChangedEventHandler(List_SelectionChanged)
change parameter of this function and set your textblock as this :
static void List_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
MessageBox.Show("clist _SelectionChanged1");
txtblkShowSelectedValue.Text=this.lines[(sender as Listbox).SelectedIndex].ToString()
}
Afteralli solved the problem like this:
lines.SelectionChanged += (o, e) =>
{
MessageBox.Show("clist _SelectionChanged1");
txtblk1ShowStatus.Text = lines.SelectedItem.ToString();
};
lines.SelectedIndex = lines.Items.Count - 1;
in my function GenerateList(..)
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, "");
}
}