Why is there an initial delay for the progress bar filling up? (Vb.Net) [duplicate] - vb.net

I'm using Windows Vista and Visual Studio 2010. Create a .Net 4 Windows Forms Application. Drop a progress bar on the default form, add code to handle the form load event and do a progressBar1.Value = 100; there.
Start debugging and you see an animation moving the progress bar to 100 in about half a second.
I need 2 progress bars in my project. One is for "global progress" and the second is for "current step progress" so the second goes from 0 to 100 and hen back to 0 for the next step. The problem is that with the progress bar being slow for some of the quick steps it never reaches 100 and it looks weird.
Is there a way to get rid of that animation? In WPF it's OK but I'd rather stay with Windows Forms.

This is just how the Vista/7 progress bar is designed. When you change the value of the progress bar, the bar is animated to that value progressively.
The only way I know of avoiding this problem is to go backwards when updating the progress bar, as follows:
progressBar1.Value = n;
if (n>0)
progressBar1.Value = n-1;
For a more complete discussion see Disabling .NET progressbar animation when changing value?

Building off of Heffernan's tip on going backwards with the progress bar and Reinhart's extension method approach in a related question, I came up with my own solution.
The solution is pretty seamless and successfully handles the issue you will encounter when the value is at Maximum. This extension method to ProgressBar alleviates the lagging that is caused from the progressive animation style present in the WinForms ProgressBar control when running on Windows Vista and 7 (I haven't tested on Windows 8 yet).
public static class ExtensionMethods
{
/// <summary>
/// Sets the progress bar value, without using 'Windows Aero' animation.
/// This is to work around a known WinForms issue where the progress bar
/// is slow to update.
/// </summary>
public static void SetProgressNoAnimation(this ProgressBar pb, int value)
{
// To get around the progressive animation, we need to move the
// progress bar backwards.
if (value == pb.Maximum)
{
// Special case as value can't be set greater than Maximum.
pb.Maximum = value + 1; // Temporarily Increase Maximum
pb.Value = value + 1; // Move past
pb.Maximum = value; // Reset maximum
}
else
{
pb.Value = value + 1; // Move past
}
pb.Value = value; // Move to correct value
}
}
Sample usage:
private void backgroundWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
progressBar.SetProgressNoAnimation(e.ProgressPercentage);
}

You can easily write a custom progress bar to show its value without animation. The following is a simple implementation to show the progress from 0 to 100 and revert to 0.
public class ProgressBarDirectRender : UserControl
{
private int _value;
public int Value
{
get { return _value; }
set
{
if (value < 0 || value > 100)
throw new ArgumentOutOfRangeException("value");
_value = value;
const int margin = 1;
using (var g = CreateGraphics())
{
if (_value == 0)
ProgressBarRenderer.DrawHorizontalBar(g, ClientRectangle);
else
{
var rectangle = new Rectangle(ClientRectangle.X + margin,
ClientRectangle.Y + margin,
ClientRectangle.Width * _value / 100 - margin * 2,
ClientRectangle.Height - margin * 2);
ProgressBarRenderer.DrawHorizontalChunks(g, rectangle);
}
}
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
ProgressBarRenderer.DrawHorizontalBar(e.Graphics, ClientRectangle);
}
}

A much simpler answer, as shown here, is to do this:
pbar.Value = value;
pbar.Value = value - 1;
pbar.Value = value;
Explanation:
It animates the PB as it increases, but not while it decreases. And that is why the above hack sppears to 'fix' the problem.

I liked Derek W's answer and I managed to find a solution which supports data binding. I inherited from System.Windows.Forms.ProgressBar and created new bindable property. Otherwise it's the same:
[DefaultBindingProperty("ValueNoAnimation")]
public class NoAnimationProgressBar : ProgressBar
{
/// <summary>
/// Sets the progress bar value, without using 'Windows Aero' animation.
/// This is to work around (hack) for a known WinForms issue where the progress bar
/// is slow to update.
/// </summary>
public int ValueNoAnimation
{
get => Value;
set
{
// To get around the progressive animation, we need to move the
// progress bar backwards.
if (value != Maximum)
Value = value + 1; // Move past
else
{
// Special case as value can't be set greater than Maximum.
Maximum = value + 1;
Value = value + 1;
Maximum = value;
}
Value = value; // Move to correct value
}
}
}
You can bind to the property like this (viewModel has an int property called Value):
var dataSource = new BindingSource { DataSource = _viewModel };
progressBarBindingHack.DataBindings.Add("ValueNoAnimation", dataSource, "Value");

Related

How to correctly update value of IntegerProperty in the view?

I am building simple application that will track a certain tabletop game of 2 players.
I have a view called MatchView
class MatchView : View() {
// data
private var currentRound = SimpleIntegerProperty(0)
private var currentTurn = SimpleIntegerProperty(0)
override val root = borderpane {
center = label(currentRound.stringBinding{ "Round %d".format(it) })
// other layout-related stuff
subscribe<EndTurnEvent> {
endPlayerTurn()
}
}
private fun endPlayerTurn() {
// increment turn
currentTurn.plus(1)
currentRound.plus(currentTurn.value % 2)
}
}
that is subscribed to EndTurnEvent - event emitted by one of the fragments used by view.
The called method is supposed to increment value of currentTurn and if needed currentRound (round increments after second player ends their turn)
However neither the value of currentRound nor the one of currentTurn are getting increased when i call .plus() method.
I have tried editting values differently :
private fun endPlayerTurn() {
// increment turn
currentTurn.value = currentTurn.value + 1
currentRound.value = currentTurn.value % 2
}
But this throws me java.lang.IllegalStateException: Not on FX application thread
I am aware that putting properties into views is anti-pattern, but since I just want to keep track of 2 properties, I thought I could put them directly into View
Platform.runLater(() -> {
// Update GUI from another Thread here
});

MRTK and Grip Press

I'm using MRTK 2.3.0 trying to catch a "Grip Press" event from the Mixed Reality motion controller.
I've setup the Input Action in the MRTK Toolkit in the Hierarchy of Unity. I've also assigned the action to the controller's grip button in the Controller Definitions. I'm using the following code and made sure the Grip variable is assigned to the Grip Press event. Nothing happens... I'm able to catch touchpad and joystick, menu button press, but not Grip? Why?
According to this documentation: https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/MixedRealityConfigurationGuide.html the Grip should be a "float" as it's designed as single axis (I wonder why, since it's a button and not a trigger...). However, I'm trying to catch the event where I can... not working...
Anyone understand what the heck I'm trying to say here? (sorry, the code below also includes other events that I can catch without a hickup).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.MixedReality.Toolkit.Input;
using Microsoft.MixedReality.Toolkit;
public class TestInput : MonoBehaviour, IMixedRealityBaseInputHandler,
IMixedRealityInputHandler<Vector2>, IMixedRealityInputHandler
{
public MixedRealityInputAction Trigger, Grip, Scroll, Swipe, Joystick, DPad, TouchPadClicked, TouchPadTouched, MenuPressed;
public MixedRealityInputAction DPadUp, DPadDown, DPadLeft, DPadRight, JoystickUp, JoystickDown, JoystickLeft, JoystickRight;
private bool TouchpadPressed, MenuButtonPressed, GrabPressed, TouchDialogPadPressed, TouchpadClicked, Thouchpadtouched,
ThumbstickActive, ThumbstickPressed, VRManipulationStarted, ScrubStarted, PlayPause = false;
private void OnEnable()
{
IMixedRealityInputSystem inputSystem;
if (MixedRealityServiceRegistry.TryGetService<IMixedRealityInputSystem>(out inputSystem))
{
inputSystem?.RegisterHandler<IMixedRealityBaseInputHandler>(this);
inputSystem?.RegisterHandler<IMixedRealityInputHandler<Vector2>>(this);
inputSystem?.RegisterHandler<IMixedRealityInputHandler>(this);
inputSystem?.RegisterHandler<IMixedRealityInputHandler<float>>(this);
}
}
private void OnDisable()
{
IMixedRealityInputSystem inputSystem;
if (MixedRealityServiceRegistry.TryGetService<IMixedRealityInputSystem>(out inputSystem))
{
inputSystem?.UnregisterHandler<IMixedRealityBaseInputHandler>(this);
inputSystem?.UnregisterHandler<IMixedRealityInputHandler<Vector2>>(this);
inputSystem?.UnregisterHandler<IMixedRealityInputHandler>(this);
inputSystem?.UnregisterHandler<IMixedRealityInputHandler<float>>(this);
}
}
public void OnInputChanged(InputEventData<Vector2> ed)
{
Debug.Log("InputChanged");
if (ed.MixedRealityInputAction == DPad)
{
Debug.Log("Touched Touchpad at:" + ed.InputData.x.ToString() + "," + ed.InputData.y.ToString());
}
if (ed.MixedRealityInputAction == Joystick)
{
Debug.Log("Touched Joystick at:" + ed.InputData.x.ToString() + "," + ed.InputData.y.ToString());
}
}
public void OnInputChanged(InputEventData ed)
{
if (ed.MixedRealityInputAction == MenuPressed)
{
Debug.Log("Menu button pressed");
//ActionText.text = "Grab pressed";
}
}
public void OnInputChanged(InputEventData<float> ed)
{
Debug.Log("Float Changed");
if (ed.MixedRealityInputAction == Grip)
Debug.Log("Grab Pressed");
}
Ok... I got this..... It's a BUG in MRTK.
I have 18 actions defined (when you have DPad left, up, down etc it goes by fast!).
When I try to assign my MixedRealityInputAction to an InputAction in the Inspector, when I try to select GrabPressed (which is the 18th action), I get
IndexOutOfRangeException: Index was outside the bounds of the array.
Microsoft.MixedReality.Toolkit.Input.Editor.InputActionPropertyDrawer.OnGUI
Therefore the action does not work....
I tried to use another InputAction instead and assign it to the grab button (I used Select in this case) and it works like a charm....
Beware....
Try
Input.GetAxisRaw(ControllerMappingLibrary.AXIS_11) > 0 || Input.GetAxisRaw(ControllerMappingLibrary.AXIS_12) > 0;
AXIS_11 is grip press for the left controller while 12 is for the right controller

Unity Input Touch issue

Could you please advise how i would go about using the input touch function in Unity to make an object changes its x direction every time the user tap on the screen. For example, for 2d setting game, an object is moving forward (to the right) in the x position, if the user tap then the object would move backward in the x position (to the left). Sorry no code is produced.
It's simple as your name "tony" :)
What you can do is to make a simple script which'd move your object to left and right. And on screen touch you can easily change its direction by just -1 multiplication.
Simple script that you can attach to your object.
using UnityEngine;
using System.Collections;
public class MoveObject : MonoBehaviour
{
float _limit = 5;
// 1 for right and -1 for left.
float _direction = 1;
// You can call it as speed
float _speed = 0.01f;
void Start ()
{
}
void Update ()
{
transform.position = Vector3.MoveTowards (transform.position, new Vector3 (transform.position.x + _direction, transform.position.y, transform.position.z), _speed);
if (Input.GetMouseButtonDown (0))
_direction *= -1;
}
}
Hope this helps :)

How to rotate windows forms in every 20 secs using timer in windows application?

I have four windows forms namely, form1.vb, form2.vb, form3.vb, form4.vb.
And also i have one master page namely form5.vb. So i have rotate one by one above four windows forms in form5.vb with every 20 secs . how to do it ?
On a 20 second timer you can call 'BringToFront' on each form.
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.bringtofront.aspx
Basically, you create a timer and call the function BringToFront on each form.
In C#:
static int counter = 1;
static void StartRotating()
{
System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
myTimer.Interval = 20000; // 20 seconds
myTimer.Tick += new EventHandler(TimerEventProcessor);
myTimer.Start();
}
private static void TimerEventProcessor(Object myObject,
EventArgs myEventArgs) {
// you could use a switch statement also
if(counter==1) form1.BringToFront();
if(counter==2) form2.BringToFront();
if(counter==3) form3.BringToFront();
if(counter==4) {
form4.BringToFront();
counter=0; //reset counter
}
counter++;
}
You need to keep an index to know which form is currently displayed and then in the timer elapsed event you can do this
formtoshow.TopMost = true;
formtoshow.BringToFront();

Edited properties who can't be set to true/false equally

It's hard to explain my problem so give me a break if it's not very clear.
I have some ten properties that can be edited in the view. Most of them are booleans. These properties configure a test environment (like one property can be configured to show the solution).
Now, the problem is that some properties can't be set to true if others are set to false. Nothing would go wrong, but it's just useless. It's like one property would be configured not to show the correct button and another to show the solution. In our system, if you can't click on the correct button, then solution will never be shown.
Does this kind of problem have a name?
Do such properties have a name (just like there are immutable properties)?
Are there best-practices to implement such a story? We can hard code it in the view, but I would rather have a generic system.
The word you're looking for is orthogonality. The settings are not orthogonal, as they can't vary independently.
As to how to handle showing these properties, the completely generic way to do it (and your problem may not warrant the coding cost of this genericicity) would be to give each control an expression that references the other controls, where if the complete expression evaluates to true (or false), the control is disabled in the view.
Easier to code would be a control that exposed an isDisabled() method, which you could override as necessary. Here's a short Java example, which leverages Java anonymous classes to do the hard work. It assumes there's already a Control class, with a booleanValue() getter that converts it to a boolean, and that since AutoDisabledControl is-a Control, it can be used as a drop-in replacement for a Control:
public class AutoDisabledControl extends Control {
public isDisabled() { return false ; }
}
..... usage ....
// control1 is never disabled
final Control1 = new AutoDisabledControl() ;
// Control2 is disabled if control1 is false
final Control2 = new AutoDisabledControl() {
public isDisabled() { return control1.booleanValue() == false; }
};
// conntrol 3 is enabled only if control1 and control2 are true
final Control1 = new AutoDisabledControl() {
public isDisabled() { return ! (
control1.booleanValue()
&& control2.booleanValue()) ;
};
Naturally, in the View's display, it checks each control's isDisabled() , and disables the ones that return true; when a Control's value is changed, the view redisplays. I'm assuming some sort of MVC Pattern.
You propably mismodeled your solution.
Try to think in a different way - perhaps U can eliminate some parameters that can be inferred from the others or u can use enumarations to combine few parameters into one.
Investigate your parameters' value space to find it out.
You could use an int or long to store the related properties and use a bit mask when setting a property to correctly clear invalid settings. This int or long could be in the form of a flagged enumeration.
[Flags]private enum BitValues
{
Bit1 = 1 << 0, //Inclusive
Bit2 = 1 << 1, //Exclusive to bit 3 and 4
Bit3 = 1 << 2, //Exclusive to bit 2 and 4
Bit4 = 1 << 3, //Exclusive to bit 2 and 3
ExclusiveBits = Bit2 | Bit3 | Bit4 //All exclusive bits
}
private BitValues enValues;
public bool Bit1
{
get { return (enValues & BitValues.Bit1) == BitValues.Bit1; }
set
{
//Clear the bit
enValues = (enValues ^ BitValues.Bit1) & enValues;
//Set the bit
enValues = enValues | BitValues.Bit1;
}
}
public bool Bit2
{
get { return (enValues & BitValues.Bit2) == BitValues.Bit2; }
set
{
//Clear exclusive bits
enValues = (enValues ^ BitValues.ExclusiveBits) & enValues;
//Set bit
enValues = enValues | BitValues.Bit2;
}
}