Using a worker thread, I am adding items to a ListView, however to do this I have implemented a delegate in the form as shown below in the code sample.
Problem:
When the ListView.Items.add() line is executed, nothing is added to the ListView
What I have tried:
I added a button, when clicked, it successfully adds a ListViewItem to the ListView object, as it should. (this is before the worker thread start, for testing/debugging)
I have also tried swapping the ListView to a RichEdit in case I had a bug in the code, but the items successfully display in the RichEdit, thus I added another ListView incase the first/previous one was buggy, and without renaming the ListView, I tried adding the items, but without success.
What happens in the Delegate:
Nothing, after the clear() method, the 4 columns each with headers disappear and nothing is added to the list view
Conclusion:
My only conclusion is that the delegate is not compatible with the ListView, since I was able to add the items to a RichEdit, but not to a ListView.
Is this a bug? Am I doing something wrong?
code sample
void connected_add_device()
{
string[] t = { "123", "-1", "sa.d.sdf.s.fg", "sda-f-sd-fgds-gf" };
if (display_connected_Devices.InvokeRequired)
display_connected_Devices.BeginInvoke((MethodInvoker)delegate ()
{
display_connected_Devices.Clear();
display_connected_Devices.Items.Add(new ListViewItem(t));
}
);
else
{
display_connected_Devices.Clear();
display_connected_Devices.Items.Add(new ListViewItem(t));
}
}
For what it is worth, I had a bad GIT commit. After everthing is fixed, this ListView (which before the GIT issue, had successfuly displayed the items) now doesn't display the items anymore.
Use display_connected_Devices.Items.Clear(); instead. Because display_connected_Devices.Clear(); will clear, like you noticed, the columns aswell.
Related
I'm facing the following issue during setting up tooltips on a WinForms / C# desktop application (using .NET Framework version 4.5).
Application has hundreds of form elements where I would like to display a tooltip.
Current implementation as the following:
I have one toolTip object on my main form
Language file has been loaded and saved in an array
There is a method which suppose to assign the tooltip texts to the different elements accordingly by calling the SetToolTip method on the toolTip object.
E.g.
toolTip.SetToolTip(backBtn, LocalizationFile[0]);
toolTip.SetToolTip(myTextBox, LocalizationFile[1]);
It works fine, tooltips are displayed correctly.
As soon as I reach ca. 30 calls it stops working.
Calling ~30 times SetToolTip method to setup the required tooltips, cause to completely stop displaying the tooltips.
The previously worked tooltip texts are not getting display anymore.
There is no exception or any error message.
Can you please explain me why the toolTip object just stops displaying the texts after calling the SetToolTip method several times? Is there any workaround out there to apply in such cases?
EDIT-1
Following workaround works, but I'm still unsure what is the original problem.
I have created a method to call SetToolTip on the toolTip object, after calling the method, I re-create the toolTip instance using the "new" operator. That solves the issue. However as I want to disable anytime the tooltips on my application I also store all the references in a List. On that list I can iterate over to enable / disable all toolTip references according to what the user wants.
Basically there is a button to toggle the tooltips.
Do you have any idea, why this actually solves the original issue?
List<ToolTip> storeToolTipReferences = new List<ToolTip>(); //store tooltip references
//method begin called to set the tooltip on a control, store the reference of the tooltip and create a new instance
private void SetMyToolTip(Control ctrl, string toolTipText)
{
toolTip.SetToolTip(ctrl, toolTipText);
storeToolTipReferences.Add(toolTip);
toolTip = new ToolTip();
}
//called as the application loads or the user changes the language
private void SetAppLanguage(string[] LocalizationText)
{
storeToolTipReferences.ForEach(e => e.RemoveAll());
SetMyToolTip(ctrl1, LocalizationText[1]);
SetMyToolTip(ctrl2, LocalizationText[2]);
SetMyToolTip(ctrl3, LocalizationText[3]);
.....
}
//logic for tooltip enable/disable in my application
storeToolTipReferences.ForEach(t => t.Active = tooltip_control.Checked);
Thank you!
I would like to update some or all of my listview's items and subitems contents with a timer (1 second refresh) But the listview flicker each one second. Sometimes the subitems are lost during redrawing. Because my listview contains data that is to be likely changed anytime, I use a timer.
Code:
I put this function in the timer's Tick method
void Refresh()
{
foreach(string s in lsttring)
{
lv.items.add(s);
lv.items[i].subitems.add(i);
}
}
I expect only items content (item text and subitem text) that are changed will be changed not the whole listview along with the timer tick.
The ListView control supports double buffering, it maps the DoubleBuffered property to the native control's LVS_EX_DOUBLEBUFFER style flag. It is quite effective but you can't get to it directly since it is a protected property. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form, replacing the old one.
using System;
using System.Windows.Forms;
class BufferedListView : ListView {
public BufferedListView() {
this.DoubleBuffered = true;
}
}
Try this:
void Refresh()
{
lv.BeginUpdate();
foreach(string s in lsttring)
{
lv.items.add(s);
lv.items[i].subitems.add(i);
}
lv.EndUpdate();
}
In this manner you update all the items and listview will be refreshed only at the end of this operation.
From Microsoft:
...if you want to add items one at a time using the Add method of the
ListView.ListViewItemCollection class, you can use the BeginUpdate
method to prevent the control from repainting the ListView every time
that an item is added. When you have completed the task of adding
items to the control, call the EndUpdate method to enable the ListView
to repaint. This way of adding items can prevent flickered drawing of
the ListView when lots of items are being added to the control.
I'm currently working on a report using Telerik Reporting (release Q1 2013), and I'm attempting to add a textbox at runtime to a header (and eventually the detail section as well), but the issue is the textbox that gets added does not show up. I'm not sure why it's not displaying, but there are no errors that occur after it is added. Right now I'm trying to add it during the itemdatabinding event. My code is below:
public partial class _WellPlateReport : Telerik.Reporting.Report
{
public _WellPlateReport(Dictionary<string, object> ReportParameters)
{
//
// Required for telerik Reporting designer support
//
InitializeComponent();
tbGenotype.Visible = false;
//
// TODO: Add any constructor code after InitializeComponent call
//
}
private void labelsGroupHeaderSection_ItemDataBinding(object sender, EventArgs e)
{
string temp = "";
Telerik.Reporting.Processing.GroupSection headerGroup = (Telerik.Reporting.Processing.GroupSection)sender;
Telerik.Reporting.TextBox tb = new Telerik.Reporting.TextBox();
tb.Left = new Telerik.Reporting.Drawing.Unit(0.5, UnitType.Inch) + tbGenotype.Left + tbGenotype.Width;
//tb.Width = new Telerik.Reporting.Drawing.Unit(3.0, UnitType.Inch);
tb.Size = tbSex.Size;
tb.Name = "TestLabel1";
tb.Value = "Test Label";
tb.Location = new Telerik.Reporting.Drawing.PointU(tbGenotype.Left + tbGenotype.Width + new Telerik.Reporting.Drawing.Unit(0.5, UnitType.Inch), Telerik.Reporting.Drawing.Unit.Inch(0D));
//this.labelsGroupHeaderSection.Items.Add(tb);
//this.Items.AddRange(new Telerik.Reporting.ReportItemBase[] { tb });
this.labelsGroupHeaderSection.Items.AddRange(new Telerik.Reporting.ReportItemBase[] { tb });
}
}
The tbGenotype is another textbox that the new textbox will be added next to at runtime, so i'm using the positioning of that to place the dynamic textboxes. There is an unknown number of additional columns that will need to be added, but I'm not sure why this isn't working. My searches showed others adding controls in a similar way.
Update: Also note, that the textbox tbGenotype was added in the designer in visual studio. Trying to set the visible property on that works, but adding the textbox to the header does not.
Try to look at this documentation. The only difference that I noticed was that they are adding the textbox to a panel. Then they are adding panel to the report. Check if tbGenotype is added in a panel or not but I think that every element you put in a report has to be in same panel first.
I have the same problem, but I notice when I refresh the report with the refresh button inside the report viewer (in my windows application; should be the same for the web version), the dynamically added controls show up. When I refresh a second time, an additional (second) set of controls shows up.
My observation is this: on initial run, the controls are added, but not visible (regardless of the visible property value being true). On first refresh (second server/application run), a second set of controls is added, not visible, and the first set is now visible. On the second refresh / third run, a third set of not visible controls is added, and the first 2 sets of controls are shown.
First, I need to clear my parent panel(s) of all dynamically added items before adding again. But, to the point of the question, calling ReportViewerInstance.RefreshReport() should cause the dynamically added controls to become visible before the initial rendering of the report. I am about to try this scenario. I am not certain yet how I am going to call the instance of the report viewer, but at minimum, I should be able to pass a reference to the instance as a report parameter, or similar.
RefreshReport() call found in this Telerik help post:
I will update with my results after trying the above.
UPDATE: RefreshReport did NOT work for me - it cancelled the processing and resulted in no report. However, I did solve my issue. And, it should solve the OP's issue as well.
Eric's code shows trying to create and show the dynamically added controls in an ItemDataBinding event. I was doing the same, and also tried ItemDataBound. Both of these events occur when processing is in action, and a help topic regarding a dynamically added table control tipped me off. The Telerik expert recommended not altering the report items during processing to avoid unpredictable behavior. Following that, I moved my code to create controls into a method (not an event) and call it from my Report.NeedDataSource event, after instantiating all needed data objects, and before setting the report datasource as one of my object collections. This works great!
I hope this helps someone else!
I've been trying to fix this issue and it seems to be a problem from the .Net framework. anyway, I have a listview which contains 5000+ items and a button used to do further processing to the selected items in the listview. now clicking this button should also set "listview.HeaderStyle" property of the listview to "ColumnHeaderStyle.Nonclickable".
now when I do that. the program hangs for like 10 seconds then continues its work. I have no idea what is causing and why this is happening. I hope you guys have a solution for this.
any ideas?
I've found a basic solution for now, all I need is to set
myListview.ColumnClick += new ColumnClickEventHandler(delegate{});
Now I don't need to change "listview.HeaderStyle" property anymore.
basically I was disabling the ColumnClick event from the HeaderStyle property and that's all. so instead of setting the HeaderStyle to nonClickable. I just remove/change the function inside event handler.
You can solve this problem using BackgroundWorker MSDN.
Note : Even using this solution your form will hang for some time. Because you have 5000+ items to be bind to the list, which will block your UI thread, hence winform will hang. But your listview.HeaderStyle will get modified.
Try this
On button click, you directly change the propert of listview.HeaderStyle to ColumnHeaderStyle.Nonclickable. Then call RunWorkerAsync of BackgroundWorker.
On DoWork event handler you do the processing, and once done bind data to list view. To do this you will need to add following extension class to your project.
Extension Class
public static class ControlExtensions
{
public static void Invoke(this Control control, Action action)
{
if (control.InvokeRequired) control.Invoke(new MethodInvoker(action), null);
else action.Invoke();
}
}
Using this you can bind data to listview
listview.Invoke(() => ( listview.DataSource = dataSource; });
Hope this works for you.
I would like to update some or all of my listview's items and subitems contents with a timer (1 second refresh) But the listview flicker each one second. Sometimes the subitems are lost during redrawing. Because my listview contains data that is to be likely changed anytime, I use a timer.
Code:
I put this function in the timer's Tick method
void Refresh()
{
foreach(string s in lsttring)
{
lv.items.add(s);
lv.items[i].subitems.add(i);
}
}
I expect only items content (item text and subitem text) that are changed will be changed not the whole listview along with the timer tick.
The ListView control supports double buffering, it maps the DoubleBuffered property to the native control's LVS_EX_DOUBLEBUFFER style flag. It is quite effective but you can't get to it directly since it is a protected property. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form, replacing the old one.
using System;
using System.Windows.Forms;
class BufferedListView : ListView {
public BufferedListView() {
this.DoubleBuffered = true;
}
}
Try this:
void Refresh()
{
lv.BeginUpdate();
foreach(string s in lsttring)
{
lv.items.add(s);
lv.items[i].subitems.add(i);
}
lv.EndUpdate();
}
In this manner you update all the items and listview will be refreshed only at the end of this operation.
From Microsoft:
...if you want to add items one at a time using the Add method of the
ListView.ListViewItemCollection class, you can use the BeginUpdate
method to prevent the control from repainting the ListView every time
that an item is added. When you have completed the task of adding
items to the control, call the EndUpdate method to enable the ListView
to repaint. This way of adding items can prevent flickered drawing of
the ListView when lots of items are being added to the control.