V3125 False Positive - pvs-studio

PVS Studio throws V3125: The 'control.Parent' object was used after it was verified against null. Check lines: 11, 9.
using System.Windows.Forms;
namespace V3125_False_Positive
{
static class Program
{
static void Main()
{
if (new Control() is Control control && control.Parent != null)
{
string parentname = control.Parent.Name;
}
}
}
}
Is this a false positive?

Indeed, this is a false positive. We'll look into it and try fixing it for the next release (actually, for the release after the next one, as we are planning to release a new version in about a week, so the fix will not make it).
Thanks for the tip!

Related

I can't use a Winforms Control created with a Class

I was looking for a Circular Picture Box for my app and I stumbled across this code (IT IS NOT MINE) and I've tried as many times as I could but I can't find any mistake. I have followed every step that was made in the tutorial for this Rounded Picture Box so it can't be a miscopy because it was working perfectly in the tutorial.
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
namespace New_Radio_Barcelona.Controls
{
class RashiCircularPictureBox : PictureBox
{
private int border = 2;
private Color colorBorder = Color.RoyalBlue;
private Color colorBorder2 = Color.HotPink;
private DashStyle borderstyle = DashStyle.Solid;
private DashCap borderCap = DashCap.Flat;
private float gradiant = 50f;
public RashiCircularPictureBox()
{
this.Size = new Size(95, 95);
this.SizeMode = PictureBoxSizeMode.StretchImage;
}
public int Border
{
get
{
return border;
}
set
{
border = value;
this.Invalidate();
}
}
public Color ColorBorder
{
get
{
return colorBorder;
}
set
{
colorBorder = value;
this.Invalidate();
}
}
public Color ColorBorder2
{
get
{
return colorBorder2;
}
set
{
colorBorder2 = value;
this.Invalidate();
}
}
public DashStyle Borderstyle
{
get
{
return borderstyle;
}
set
{
borderstyle = value;
this.Invalidate();
}
}
public DashCap BorderCap
{
get
{
return borderCap;
}
set
{
borderCap = value;
this.Invalidate();
}
}
public float Gradiant
{
get
{
return gradiant;
}
set
{
gradiant = value;
this.Invalidate();
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.Size = new Size(this.Width, this.Width);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
var graphic = pe.Graphics;
var rect = Rectangle.Inflate(this.ClientRectangle, -1, -1);
var rectborder = Rectangle.Inflate(rect, -border, -border);
var size = border > 0 ? border * 3 : 1;
using (var bordercolorG = new LinearGradientBrush(rectborder, colorBorder, colorBorder2, gradiant))
using (var path = new GraphicsPath())
using (var pen = new Pen(this.Parent.BackColor, border))
using (var penborder = new Pen(bordercolorG, size))
{
graphic.SmoothingMode = SmoothingMode.AntiAlias;
penborder.DashStyle = borderstyle;
penborder.DashCap = borderCap;
path.AddEllipse(rect);
this.Region = new Region(path);
graphic.DrawEllipse(pen, rect);
if (border > 0)
{
graphic.DrawEllipse(penborder, rectborder);
}
}
}
}
}
I compile the project and then try to add it to the Design tab as shown in the tutorial. It says it could not be loaded. I was trying to understand what is not working properly but I still do not find the mistake. Some help plis?
Another aspect to take into consideration is the fact that in class RashiCircularPictureBox : PictureBox puts 1 reference above the code and in public RashiCircularPictureBox() it says 0 references. It may be for this but I'm no expert on Classes and I'm stuck in this stupidity. if anyone could clear my mind about this issue I would be so grateful about it
The designer in most versions of Visual Studio up until recently has been a 32-bit process. So if the control was built as 64-bit, it wouldn’t be able to load it at design-time, but VS would still be able to create 64-bit applications that can use the 64-bit control at runtime.
This means if you build your control as 32-bit or AnyCPU, it should solve the design-time loading problem.
The release notes of Visual Studio 2022 version 17.0.0 state that “devenv.exe is now 64-bit only”. I haven’t tried this myself, but it probably means you can now use 64-bit controls at design time with the newer versions of VS.
In all cases, AnyCPU should work.

V3125 false positive when having empty statement after return

This minimal example triggers V3125 about member being used after it was verified against null. If I remove the extra semicolon after the first return statement V3125 is no longer triggered.
public class PVS_nullcheck
{
private object member;
public int Method()
{
if (member == null)
{
return 0;
; // <-- 3125
}
return member.GetHashCode();
}
}
Thank you for the feedback. We have fixed this false alarm, the fix will be available in the next release version of PVS-Studio. You can download the latest beta from here.

How to stop pivot looping

I want to create a wizard control from the pivot control. To achieve this I need to stop the pivot looping. I want to stop the pivot control moving forward from the last item to the first and backwards from the first to the last.
I'm pretty sure I should be able to intercept the manipulations e.g. cancel if I detect a right to left manipulation on the last pivot item. I can capture this in ManipulationDelta but don't know how to cancel the manipulation.
I have tried setting e.Handled = True but it didn't work.
I tried to set IsHitTestVisisble to false but this kills all manipulations. I tried setting it back to true in ManipulationCompleted but this then allows all manipulations.
Any ideas?
Cheers
Steve
The pivot is not designed to be used as a wizard and does not support stopping it's looping behaviour as this would create an inconsistent UX for users.
If you really must create a wizard do it with multiple pages.
Don't use a Pivot for a Wizard. Create your own transitions instead.
I couldn't reply to your comment on Matts answer but I just wanted to point you to this:
http://forty3degrees.wordpress.com/2011/07/19/creating-a-swipable-contentcontrol/
It's the last entry in my very neglected blog and should provide a good base for creating a wizard using a pivot style swipe.
Calum.
EDIT: I tried to do what you wanted with the pivot but couldn't find a way to stop it looping. The only way that I can think of to achieve this would be to derive a custom control from Pivot. Unfortunately SelectedIndex/SelectedItem are not virtual so you would need to hide them (with the new modifier) and reproduce the logic from the base class.
It's just an alternative solution I've posted here - you can try to make use of XNA framework TouchPanel and Touch.FrameReported Event:
using Microsoft.Xna.Framework.Input;
public MainPage()
{
InitializeComponent();
myPivot.IsHitTestVisible = false; // disable your Pivot
Touch.FrameReported += Touch_FrameReported;
TouchPanel.EnabledGestures = GestureType.HorizontalDrag;
}
TouchPoint first;
private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
TouchPoint mainTouch = e.GetPrimaryTouchPoint(this);
if (mainTouch.Action == TouchAction.Down)
first = mainTouch;
else if (mainTouch.Action == TouchAction.Up && TouchPanel.IsGestureAvailable)
{
if (mainTouch.Position.X < first.Position.X)
{
if (myPivot.SelectedIndex < myPivot.Items.Count - 1)
myPivot.SelectedIndex++;
}
else if (mainTouch.Position.X > first.Position.X)
{
if (myPivot.SelectedIndex > 0)
myPivot.SelectedIndex--;
}
}
}
Thought it would probably work from WP7.1 as TouchPanel is available from that version of the OS.
If you absolutely want to keep the Pivot from looping, here is a quick and dirty hack:
int previousSelectedIndex = 0;
public PageWithPivot()
{
InitializeComponent();
pivot.SelectionChanged += new SelectionChangedEventHandler(pivot_SelectionChanged);
}
private void pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (pivot.SelectedIndex == 0 && previousSelectedIndex == <number Of screens - 1>)
pivot.SelectedIndex = <number Of screens - 1>;
previousSelectedIndex = pivot.SelectedIndex;
}
This causes your PivotControl to jump back to the last pivotItem. Not very pretty but works.
This is so weird because it only works in the Emulator. I guess you shan't mess with the UI
You can use MVVM:
<phone:Pivot Foreground="Black"
Name="pivot1"
Title="AIDE"
SelectedIndex="{Binding SelectedItem, Mode=TwoWay}">
Cs:
private class HelpViewModel : ViewModelBase
{
public HelpViewModel()
{
}
private int _SelectedItem = 0;
public int SelectedItem
{
get
{
return _SelectedItem;
}
set
{
if (_SelectedItem != value)
{
if (value == 3)
_SelectedItem = 0;
else
_SelectedItem = value;
RaisePropertyChanged(() => SelectedItem);
}
}
}
}
public AppHelpPivot()
{
InitializeComponent();
LayoutRoot.DataContext = new HelpViewModel();
}

How to use Code Contracts with query?

I am fairly new to Code Contracts...and I ran into a problem.
I have in a method LINQ query that go something like this:
MyClass[] fields =
(from p in rType.GetProperties()
where p.CanRead
let fAttr = p.GetCustomAttributes(typeof(MyClassAttribute), true).SingleOrDefault() as MyClassAttribute
where fAttr != null
select new MyClass(p, fAttr)).ToArray();
And I want to implement Code Contracts in my project. I have done everything OK, until I got to this point. When I run static checker, it suggest to me that I need to add a couple of preconditions (Contract.Requires) regarding variables p and fAttr which are defined in the query. And also, I have a couple of unproven requires.
How can I solve this? Any ideas?
MyClass also contains two preconditions:
internal MyClass(PropertyInfo p, MyClassAttribute att)
{
Contract.Requires(p != null);
Contract.Requires(att != null);
...
}
Thanks in advance :)
I can't seem to reproduce this. Are you using the latest version of Code Contracts?
My entire code looks like this... is this close enough to your version?
using System;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Reflection;
namespace ConsoleApplication10
{
class Program
{
class MyClassAttribute : Attribute{}
class MyClass
{
internal MyClass(PropertyInfo p, MyClassAttribute a)
{
Contract.Requires(p != null);
Contract.Requires(a != null);
}
}
static void Main(string[] args)
{
var rType = typeof (DateTime);
MyClass[] result = (from p in rType.GetProperties()
where p.CanRead
let fAttr = p.GetCustomAttributes(typeof(MyClassAttribute), true).SingleOrDefault() as MyClassAttribute
where fAttr != null
select new MyClass(p, fAttr)).ToArray();
}
}
}

How to tell if .NET code is being run by Visual Studio designer

I am getting some errors thrown in my code when I open a Windows Forms form in Visual Studio's designer. I would like to branch in my code and perform a different initialization if the form is being opened by designer than if it is being run for real.
How can I determine at run-time if the code is being executed as part of designer opening the form?
if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
{
// Design time logic
}
To find out if you're in "design mode":
Windows Forms components (and controls) have a DesignMode property.
Windows Presentation Foundation controls should use the IsInDesignMode attached property.
The Control.DesignMode property is probably what you're looking for. It tells you if the control's parent is open in the designer.
In most cases it works great, but there are instances where it doesn't work as expected. First, it doesn't work in the controls constructor. Second, DesignMode is false for "grandchild" controls. For example, DesignMode on controls hosted in a UserControl will return false when the UserControl is hosted in a parent.
There is a pretty easy workaround. It goes something like this:
public bool HostedDesignMode
{
get
{
Control parent = Parent;
while (parent!=null)
{
if(parent.DesignMode) return true;
parent = parent.Parent;
}
return DesignMode;
}
}
I haven't tested that code, but it should work.
The most reliable approach is:
public bool isInDesignMode
{
get
{
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
bool res = process.ProcessName == "devenv";
process.Dispose();
return res;
}
}
The most reliable way to do this is to ignore the DesignMode property and use your own flag that gets set on application startup.
Class:
public static class Foo
{
public static bool IsApplicationRunning { get; set; }
}
Program.cs:
[STAThread]
static void Main()
{
Foo.IsApplicationRunning = true;
// ... code goes here ...
}
Then just check the flag whever you need it.
if(Foo.IsApplicationRunning)
{
// Do runtime stuff
}
else
{
// Do design time stuff
}
I had the same problem in Visual Studio Express 2013. I tried many of the solutions suggested here but the one that worked for me was an answer to a different thread, which I will repeat here in case the link is ever broken:
protected static bool IsInDesigner
{
get { return (Assembly.GetEntryAssembly() == null); }
}
The devenv approach stopped working in VS2012 as the designer now has its own process. Here is the solution I am currently using (the 'devenv' part is left there for legacy, but without VS2010 I am not able to test that though).
private static readonly string[] _designerProcessNames = new[] { "xdesproc", "devenv" };
private static bool? _runningFromVisualStudioDesigner = null;
public static bool RunningFromVisualStudioDesigner
{
get
{
if (!_runningFromVisualStudioDesigner.HasValue)
{
using (System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess())
{
_runningFromVisualStudioDesigner = _designerProcessNames.Contains(currentProcess.ProcessName.ToLower().Trim());
}
}
return _runningFromVisualStudioDesigner.Value;
}
}
/// <summary>
/// Are we in design mode?
/// </summary>
/// <returns>True if in design mode</returns>
private bool IsDesignMode() {
// Ugly hack, but it works in every version
return 0 == String.CompareOrdinal(
"devenv.exe", 0,
Application.ExecutablePath, Application.ExecutablePath.Length - 10, 10);
}
System.Diagnostics.Debugger.IsAttached
It's hack-ish, but if you're using VB.NET and when you're running from within Visual Studio My.Application.Deployment.CurrentDeployment will be Nothing, because you haven't deployed it yet. I'm not sure how to check the equivalent value in C#.
using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess())
{
bool inDesigner = process.ProcessName.ToLower().Trim() == "devenv";
return inDesigner;
}
I tried the above code (added a using statement) and this would fail on some occasions for me. Testing in the constructor of a usercontrol placed directly in a form with the designer loading at startup. But would work in other places.
What worked for me, in all locations is:
private bool isDesignMode()
{
bool bProcCheck = false;
using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess())
{
bProcCheck = process.ProcessName.ToLower().Trim() == "devenv";
}
bool bModeCheck = (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime);
return bProcCheck || DesignMode || bModeCheck;
}
Maybe a bit overkill, but it works, so is good enough for me.
The success in the example noted above is the bModeCheck, so probably the DesignMode is surplus.
You check the DesignMode property of your control:
if (!DesignMode)
{
//Do production runtime stuff
}
Note that this won't work in your constructor because the components haven't been initialized yet.
When running a project, its name is appended with ".vshost".
So, I use this:
public bool IsInDesignMode
{
get
{
Process p = Process.GetCurrentProcess();
bool result = false;
if (p.ProcessName.ToLower().Trim().IndexOf("vshost") != -1)
result = true;
p.Dispose();
return result;
}
}
It works for me.
I'm not sure if running in debug mode counts as real, but an easy way is to include an if statement in your code that checkes for System.Diagnostics.Debugger.IsAttached.
If you created a property that you don't need at all at design time, you can use the DesignerSerializationVisibility attribute and set it to Hidden. For example:
protected virtual DataGridView GetGrid()
{
throw new NotImplementedException("frmBase.GetGrid()");
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int ColumnCount { get { return GetGrid().Columns.Count; } set { /*Some code*/ } }
It stopped my Visual Studio crashing every time I made a change to the form with NotImplementedException() and tried to save. Instead, Visual Studio knows that I don't want to serialize this property, so it can skip it. It only displays some weird string in the properties box of the form, but it seems to be safe to ignore.
Please note that this change does not take effect until you rebuild.
We use the following code in UserControls and it does the work. Using only DesignMode will not work in your app that uses your custom user controls as pointed out by other members.
public bool IsDesignerHosted
{
get { return IsControlDesignerHosted(this); }
}
public bool IsControlDesignerHosted(System.Windows.Forms.Control ctrl)
{
if (ctrl != null)
{
if (ctrl.Site != null)
{
if (ctrl.Site.DesignMode == true)
return true;
else
{
if (IsControlDesignerHosted(ctrl.Parent))
return true;
else
return false;
}
}
else
{
if (IsControlDesignerHosted(ctrl.Parent))
return true;
else
return false;
}
}
else
return false;
}
Basically the logic above boils down to:
public bool IsControlDesignerHosted(System.Windows.Forms.Control ctrl)
{
if (ctrl == null) return false;
if (ctrl.Site != null && ctrl.Site.DesignMode) return true;
return IsControlDesignerHosted(ctrl.Parent);
}
If you are in a form or control you can use the DesignMode property:
if (DesignMode)
{
DesignMode Only stuff
}
I found the DesignMode property to be buggy, at least in previous versions of Visual Studio. Hence, I made my own using the following logic:
Process.GetCurrentProcess().ProcessName.ToLower().Trim() == "devenv";
Kind of a hack, I know, but it works well.
System.ComponentModel.Component.DesignMode == true
To solve the problem, you can also code as below:
private bool IsUnderDevelopment
{
get
{
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
if (process.ProcessName.EndsWith(".vshost")) return true;
else return false;
}
}
Here's another one:
//Caters only to thing done while only in design mode
if (App.Current.MainWindow == null){ // in design mode }
//Avoids design mode problems
if (App.Current.MainWindow != null) { //applicaiton is running }
After testing most of the answers here, unfortunately nothing worked for me (VS2015).
So I added a little twist to JohnV's answer, which didn't work out of the box, since DesignMode is a protected Property in the Control class.
First I made an extension method which returns the DesignMode's Property value via Reflection:
public static Boolean GetDesignMode(this Control control)
{
BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static;
PropertyInfo prop = control.GetType().GetProperty("DesignMode", bindFlags);
return (Boolean)prop.GetValue(control, null);
}
and then I made a function like JohnV:
public bool HostedDesignMode
{
get
{
Control parent = Parent;
while (parent != null)
{
if (parent.GetDesignMode()) return true;
parent = parent.Parent;
}
return DesignMode;
}
}
This is the only method that worked for me, avoiding all the ProcessName mess, and while reflection should not be used lightly, in this case it did all the difference! ;)
EDIT:
You can also make the second function an extension method like this:
public static Boolean IsInDesignMode(this Control control)
{
Control parent = control.Parent;
while (parent != null)
{
if (parent.GetDesignMode())
{
return true;
}
parent = parent.Parent;
}
return control.GetDesignMode();
}
For WPF (hopefully this is useful for those WPF people stumbling upon this question):
if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
}
GetIsInDesignMode requires a DependencyObject. If you don't have one, just create one.
/// <summary>
/// Whether or not we are being run from the Visual Studio IDE
/// </summary>
public bool InIDE
{
get
{
return Process.GetCurrentProcess().ProcessName.ToLower().Trim().EndsWith("vshost");
}
}
Here's a flexible way that is adaptable to where you compile from as well as whether or not you care which mode you're in.
string testString1 = "\\bin\\";
//string testString = "\\bin\\Debug\\";
//string testString = "\\bin\\Release\\";
if (AppDomain.CurrentDomain.BaseDirectory.Contains(testString))
{
//Your code here
}

Resources