I have created a form that displays a chart using Microsoft's DataVisualization.Charting.Chart control (I use version 4 of the .NET framework). I also draw some annotations on the chart, and to locate them I need to know about the chart axes.
The code
myChart.ChartAreas[0].AxisX.ValueToPixelPosition(location)
gives me a NullReferenceException. The chart is definitely instantiated and I can set properties of the AxisX- for instance, myChart.ChartAreas[0].AxisX.Maximum = 1 works fine.
Drilling into the exception message, it looks like the trouble is in the GetLinearPosition method, which is something internal to the Chart control:
at System.Windows.Forms.DataVisualization.Charting.Axis.GetLinearPosition(Double axisValue)
at System.Windows.Forms.DataVisualization.Charting.Axis.GetPosition(Double axisValue)
at System.Windows.Forms.DataVisualization.Charting.Axis.ValueToPixelPosition(Double axisValue)
Does anyone have any insight to get me started fixing this? Thanks in advance!
This answer came in a comment to the question from Hans Passant:
That rings a bell. I think the trouble is that this can't work until
the control has figured out its data-to-display mapping. Which doesn't
happen until it needs to paint itself, in typical lazy fashion. Call
Update() first, something like that.
Which got me far enough to make this discovery:
You figured it out, Hans. The chart is on a TabControl tab, and I had
to bring that tab to front (with the TabControl.SelectedTab property)
before making the call to ValueToPixelPosition.
Related
My issue is in the .NET framework using C# to create a simple form application that contains a rich text box (RTB) control.
Briefly the issue I am experiencing is that when trying to clear the contents (.Text) of the RTB, the scroll bar doesn't go away. I would like to know if there is anything inherently wrong with the way I am using the RTB. I apologize, but the site will not allow me to post images yet. So if there is a misunderstanding regarding what "doesn't go away" means, please ask!
So first, I write data to the box using the following code snippet:
// append the new message
this.rtb_receive_0.Text += message;
this.rtb_receive_0.SelectionStart = this.rtb_receive_0.Text.Length;
this.rtb_receive_0.ScrollToCaret();
Later on, I clear the RTB contents (RTB.Text) with the following code:
this.rtb_receive_0.Text = String.Empty;
this.rtb_receive_0.Refresh();
In the above code I have attempted to fix my problem with the, "Refresh," method. However it does not seem to be doing the job.
When I clear the RTB contents, the scroll bar does not go away... I noticed that if I grab another window and drag it over the top of the application, that the frozen scroll bar disappears. Also, I can minimize the application, then maximize it again and the bar will disappear. There has to be a way to prevent this frozen scroll bar from happening in the first place though.
Per the answer, here was the fix to stop the bar from freezing up:
this.rtb_receive_0.Text = String.Empty;
this.rtb_receive_0.Clear();
this.rtb_receive_0.ScrollBars = RichTextBoxScrollBars.None;
this.rtb_receive_0.ScrollBars = RichTextBoxScrollBars.Vertical;
this.rtb_receive_0.Refresh();
Have you tried simply just programatically setting the Scrollbars property on the RTB?
myRichTextBox.ScrollBars = RichTextBoxScrollBars.None;
Edit: I think I misinterpreted what you needed. Searching around, I found this similar post on another forum: http://www.vbforums.com/showthread.php?793671-RESOLVED-RichTextBox-Visual-Bug
This user is setting the value of an RTB based on a selection in a list view. When a new value is set and does not require a scrollbar it doesn't re-draw and still shows the bar.
It seems like adding myRichTextBox.Clear(); myRichTextBox.Refresh(); should help. In this case that user is also programatically setting the ScrollBars property as well.
Also, are you able to determine how many lines of text can fit in the RichTextBox before a scrollbar is needed? I suppose that might vary based on system settings on the machine, but you might just be able to programatically check myrtb.Scrollbars = (myrtb.Lines.Length > X) ? Vertical : None; (excuse the psuedo code syntax)
What helped for me was just calling the refresh() method twice. Very ugly, but it does the job.
Hmm, after more thorough testing this ugly fix proved to be not so much of a fix afterall. It helps, but still some glitches.
refresh();
update();
seems like a better solution.
I was having this same problem. I solved it by calling the Invalidate() method which forces the control to repaint.
Me.RichTextBox.Clear()
'Call Invalidate in order to force the RichTextBox to repaint. I do this so that any
'Visible Scroll bars are removed after clearing the Text
Me.RichTextBox.Invalidate()
I tried with Refresh(); Update(); Invalidate();,but it didn't worked for me.
I solved this problem using following three lines :-
RitchTextBox.Clear(); //Clearing text in RichTextBox
RitchTextBox.ScrollBars = RichTextBoxScrollBars.None; //Remove scroll
RitchTextBox.ScrollBars = RichTextBoxScrollBars.Vertical; //Again add scroll
Try those above three lines. It will work 100%.
I'm trying to implement the automation test via UIAutomation for our project. But lots of the controls are not standrad, and proper patterns are also not implemented for that controls. How should I to manipulate the controls via UIAutomation framework in this case?
For example, a button in our product is implemented via a Pane, and the invoked pattern is not implemented as well. How should I click the button? (To avoid installing VS on the test machine, I don't want to use Mouse.Click() in Microsoft.VisiualStudio.TestTools.UITesting namespace) Is there a way to do that only using UIAutomation framework or something else embedded in .net framework? Thanks in advance! (If the proper pattern is implemented, Below code will work. And as a new user, I cannot post the screenshot for your reference, sorry!)
object temp = null;
if (btnTest.TryGetCurrentPattern(InvokePattern.Pattern, out temp))
{
InvokePattern btnTestPattern = temp as InvokePattern;
btnTestPattern.Invoke();
}
The only way to interact when Control Patterns are not implemented is to go clicking around stuff.
I would suggest try following to avoid maximum errors.
Before sending the click, make sure the parent of button(pane or window is set to foreground)
Instead of sending the click to corner of the AutomationElement, try sending it in midpoint, of the element,
Also, try hovering over the element first, the wait like 200ms, and then send click, So that you are sure to see execution.[Trust me, this helps debugging a lot and avoids many issues.]
The best thing would be, if those guys who implement the system would implement server-side UIA provider to their UI Elements!
But often that's not possible..., I used the following workaround (at least for clicking/toggling):
AutomationElement yourAE = ...// some code to find the right AutomationElement (AE)
clickablePoint = yourAE.GetClickablePoint();
also BoundingRectangleProperty could be of help
If you receive that clickable point you can use
System.Windows.Forms.Cursor.Position = new System.Drawing.Point((int)clickablePoint.X, (int)clickablePoint.Y);
to move to the location, and than click it via InputSimulator or some win32 (user32.dll) commands.
(note: of course you can also use InputSimulator or win32 to move the mouse - but I had some problems with the InputSimulator when it came to several screens with different locations or resolutions - so Cursor.Position was the easiest approach, which is also very reliable)
I don't know if I'm just not understanding what I've found so far, or if it really is too complex to apply to such a simple idea as it seems. I'm trying to bind a button's height and width to variables that are stored in user settings. I can't seem to get this to work, or rather I simply don't how to, as in what commands to use. The issue lies in not knowing what to put in the Binding field of the xaml. If anyone could point to a guide that involves just this, could explain what to do I would be very appreciative.
Edit: I've solved the problem of binding the variable, it now saves to the User setting file when it should. Now I'm having an issue with the value stored in user setting beig overwritten every time the program loads with the default value. I am running this through VS debug menu selection, so I suppose the issue could lie there, but I've tried publishing it and running and still getting the same results. Any ideas?
Assuming by 'User Settings' you mean the built-in Settings not a custom implementation:
See http://blogs.windowsclient.net/bragi/archive/2008/07/03/using-settings-in-wpf-or-how-to-store-retrieve-window-pos-and-loc.aspx for an example of this - essentially you want to set up TwoWay bindings to Properties.Settings.Default: note that you have to define the settings in advance using the Settings UI, and you have to call Properties.Settings.Default.Save() when the app exits to persist the settings.
I'm posting this answer so that hopefully somebody else can read it and avoid such a ridiculous problem. First off, as far as the initial question, Staurt answered it quite nicely. But my edit above brought up a new but related problem. I ended up fixing it on accident.
The whole purpose of this was that I have a slider bar that adjusts the size of a shortcut button dock. The slider worked, but as I said above it would reset itself every time I reloaded. The issue in this case was that I have the buttons set to resize as the slider moves, so I used the slider_ValueChanged event as you can see here:
private void iconSizeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
try
{
Properties.Settings.Default.iconHeight = Convert.ToInt32(iconSizeSlider.Value);
Properties.Settings.Default.iconWidth = Convert.ToInt32(iconSizeSlider.Value * 1.3);
Properties.Settings.Default.Save();
//iconWidth.Text = buttonWidth.ToString();
//ButtonRefresh();
}
catch (FormatException)
{
}
}
While trying to use the Run To Cursor part of VS2010, I got tired of having to F11 through a multitude of loading steps, so as a debugging tool I added a bool fullyInitialized flag. This solved the problem completely. Apparently (which I didn't realize before), when the slider was first initialized it considered the value to have changed, so when it ran through the ValueChanged method, it reset everything to default. So adding a simple conditional around the try-catch to check for the fullyInitialized flag solved everything. Hopefully this helps somebody else.
I recently started getting acquainted with Visual Studio 2010 and C# for an internship. C# doesn't include a built-in InputBox function, so I made my own form, with a text box, two buttons and a simple label.
I have a function set up to allow the programmer to call the form in regular format (where the user enters input via the textbox) or yes/no format (where the form just displays a question and the yes and no buttons).
When I switch over to yes/no format, I want to center the label programmatically. I've been using the code:
labelNote.Left = inputBox.Left + (inputBox.Width / 2) - (labelNote.Width / 2);
This should put the center of the note in the center of the form. However, if the contents of the label change (making the new label longer or shorter) the properties don't update to reflect the new size. It won't center unless it includes the original text. Is there some way to force an update? I foresee this becoming a problem with positioning objects for scalability in the future.
Thank you for your time
I'm assuming you have the sizing within an actionlistener. Specifically the forms' resize action listener. Then whenever the form is resized it is called and all of you code is recalled. Then to force an update from somewhere else you just have to call the actionlistener.
Actionlistener:
Private Sub formName_Resize(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Resize
Calls actionlistener:
formName_Resize(sender, e)
Well, you could attach an event to Label.TextChanged. Frankly it would be better to change the TextAlign or something like that though: try to perform the layout in a declarative fashion instead of doing it explicitly through code. That tends to make things work rather better.
I've found the [TableLayoutPanel]1 control to be reasonably easy to work with - most of the time (and occasionally a complete pain).
It turns out that I made a stupid mistake (a common theme for me in debugging. The really small stuff goes unnoticed for the longest amount of time).
The label resizing was not the issue. The issue was the order in which I changed the contents of the label and then called the function to calculate its new location. I was calling the location calculation first, so it found where to center the label based on the old contents. I didn't notice for so long, because the text was changing properly. I took it for granted that the functions were being called in the correct order.
So, when it doubt, check the order in which you're writing your code. Thanks for you help anyway, everyone. I ended up finding out some neat things that could be applicable to other scenarios (such as the MeasureString function in the Graphics class).
I have a custom control and it works fine...except that the control cannot be rendered on Design Time. ( I am using VS 2008)
I am thinking many people who develop custom controls encounter this problem...The error I get is "Error Creating Control - CustomControlName" Object reference not set to an instance of an object.
I want a work around. or at least debug this...(Since this is a design time issue how to debug?)
I have tried if( !DesignMode) code on OnInit, OnPreRender, RenderContents, CreateChildControls Methods ( I am just shooting in the dark)...
Help pls. I really hope this is not a VS bug!
BFree's comment is the most likely issue, for a control to display in the design view it needs a parameterless constructor as the design viewer doesn't know how you would normally instantiate the control.
If you do have a parameterless constructor, can you paste some code in to show what's happening?
As Glenn mentioned the first issue could be no parameterless constructor.
The second could be you are calling methods during the OnLoad or other methods you mentioned that have parameters that are not initialized or some sort of attempt at database calls etc that is normally done at run-time.
Unless they fixed this bug recently* and I'm not aware, something to keep in mind is the DesignMode property works for the first and second level of nested controls but beyond that it normally doesn't work right. (Such as form containing a UserControl[1] that holds another UserControl[2], the DesignMode works on the form and [1] but not [2]).
Also to agree with Glenn, seeing some of the code will help.
*From my very recent experience working with nested usercontrols it hasn't been fixed.
In your OnPreRender & CreateChildControls methods it's making a call to this.Page. You might want to try wrapping them in a
if (this.Page != null)
{
.....
}
Because I don't think you'll have a Page object at that point & I'm pretty sure PreRender & CreateChildControls will be called in design view. I haven't written custom server controls for a while though, so I could be wrong (been working in MVC lately).
Glenn, the error ur getting a VS bug and no fix has been released yet.