Control.IsAccessible - winforms

I need to check if a c# WinForm Window (FORM Class) has been initialized and waiting for user events. But I could not find out how to manage that.
Therefore I had the idea to set the Control.IsAccessible Flag of the Form to true, within the OnLoad Event of the Windows Form.
My question is now, what is the Control.IsAccessible Flag origin intended for? Or is there an other solution to check if the Winform is initialized.
Thanks for your help

I do not know what IsAccessible is intended for but for the check you are doing you want Created
if(myForm.Created)
{
//Do stuff
}
I had a whole bunch of problems with it, here is one of my old question on SO that helped me out a lot with it.

Control.IsAccessible just means the control is visible to accessibility applications.
You can check myForm.Created to see if the window exists.
You can also register an event handler for the Application.Idle event, which occurs when the application has finished initializing and is ready to begin processing windows messages.
Here is a common usage:
public int Main(string[] args)
{
Application.Idle += WaitUntilInitialized;
}
private void WaitUntilInitialized(object source, EventArgs e)
{
// Avoid processing this method twice
Application.Idle -= WaitUntilInitialized;
// At this point, the UI is visible and waiting for user input.
// Begin work here.
}

Related

Extend GoBack function in NavigationWindow

I´ve a NavigationWindow with some pages. I navigate from one to another with buttons, and go back function of navigation window. My problem is I use a descriptor in some of the pages when they load, and I´d like to dispose it when you use go back function in navigationwindow (in fact the "descriptor" is Kinect, and when the page loads, it starts Kinect with sensor.start(), and I want to stop it when going back, sensor.stop()... but I think it´s the same as a file descriptor for this issue and much more people has worked with file descriptors).
Is there any way to extend the GoBack function in the page to dispose descriptors (in my code I only need to call sensor.stop(); )?
Thanks in advance
My suggestion in the comment was based on windows phone development experience.. but after i tried applying that solution in wpf using navigationwindow, i found nothing like OnNavigatedTo/OnNavigatedFrom in WP/silverlight.
But i found Navigating event of NaviagtionWindow can be used instead. In that event, you can get this.CurrentSource which is Page2 (if you navigate back from Page2 to Page1) and dispose descriptors in that Page.
Hope this work.
Ok, I found how to do a workaround. It also applies to the question: how to dispose an object in WPF. It´s weird all posts about dispose objects in WPF talk about GC and that you can´t dispose it yourself. Yes, GC dispose objects automatically, but when he wants. But maybe you want to dispose inmediately, or you have an object that needs previous operations before dispose. In my case, Kinect needs to be stopped before dispose (you can dispose without stopping, but kinect ir sensor is still working). And GC is not solution because I need to stop it before dispose.
So, the solution:
public partial class MyClass : Page
{
private KinectSensor sensor;
public MyClass()
{
InitializeComponent();
this.Loaded += (s, e) => { NavigationService.Navigating += NavigationService_Navigating; };
// What you want to add to the constructor
// I want to start Kinect
sensor = KinectSensor.KinectSensors.FirstOrDefault(k => k.Status == KinectStatus.Connected);
sensor.Start();
}
public void NavigationService_Navigating(object sender, NavigatingCancelEventArgs e)
{
if (e.NavigationMode == NavigationMode.Back)
{
// What you want to do.
// I want to stop and dispose Kinect
if (sensor != null)
{
sensor.Stop();
sensor.Dispose();
}
}
}
}

Has any one out there in the field used Dispatcher.Yield?

In "Lucian Wischik - Async Part 2 -- deep dive into the new language feature of VB/C#" for NDC 2012, the recommended use of Dispatcher.Yield is introduced to me. Does anyone out there have examples (and explanations) of how (and why) this call is used in the wild?
Well for example if you have a long running task but you still need to update your UI you can use Yield.
Yield gives you the ability to leave the current thread context and allow other code to run in the underlying context.
public async void MyButton_Click(object sender, RoutedEventArgs e)
{
for( int i=0; i < 10000; i++)
{
ProcessSomeStuff(i);
// await the Yield to ensure all waiting messages
// are processed before continuing
await Task.Yield();
}
}
In the example above you can process stuff async but calling Yield will allow events on the UI thread to execute also,
I love to use "await Dispatcher.Yield()" whenever I develop WPF applications.
It is easy to use and barely makes any problems in most cases.
The most useful case using Dispatcher.Yield() is when there is a small time of lag in a operation, which can not be bypassed by "Task", "Thread" etc.
For example, let's say that there is a command button which opens a new window or tab.
private void aButton_Click(object sender, RoutedEventArgs e)
{
// Do some ui stuff
// You can not use Task here at large.
}
What happens here is the whole application stopping, and the button UI remains pressed until the new window or tab opens. It is bad user experience and makes the apllicaiton seem so much slow.
and here is a code with a trick.
private async void aButton_Click(object sender, RoutedEventArgs e)
{
await Dispatcher.Yield();
// Do some ui stuff
}
In here, your code works differently. Dispathcer will process other ui operations first before getting into the job. The button pressed motion will be released first and then a new window will come.
Application stopping will be same, but to users the application will be much smooth and fast. So it is usually a good idea to adopt Dispatcher.Yield() in your application.
In addition, Task.Yield() is different from Dispatcher.Yield(). Try two options and see the results.

C# checkedlistbox differentiate between ItemCheck via code and mouse click

I'm using C# VS2008, WinForm application
I have a checkedlistbox control on my form (win-form application)
In the code I check some items in checkedlistbox using the SetItemChecked(index, false) method and it raise the event ItemCheck.
I also allow the user to check items in that checkedlistbox and it also raise the event ItemCheck when the user check or uncheck an item.
How can I find in the ItemCheck event how this event occur (via code or via user keyboard/mouse input)?
Thanks.
I think that there is no a simple way to differentiate the situation using code.
The only thing that comes to mind is through the use of a global form variable:
public class Form1:Form
{
bool _isCodeClick = false;
.....
// Somewhere in your code
_isCodeClick = true;
checkedListBox1.SetItemChecked(index, true);
_isCodeClick = false;
.....
private void CheckedListBox1_ItemCheck(Object sender, ItemCheckEventArgs e)
{
if(_isCodeClick == true)
{
// Do processing for click by code
}
else
{
// Do processing for click by user
}
}
}
If you go for this solution remember to take additional steps to correctly trap exceptions that could bypass the reset of the global variable to the false state.
Probably using advanced manipulation of keyboard and mouse events you could reach a reasonable way to identify what has caused the ItemCheck event, but sometime some solutions are too complex and not worth it.
EDIT: Reviewing my answer I feel the need to add a little change to reduce the maintaining problems that this esponse implies.
The code that set the boolean variable and call the SetItemChecked should be encapsulated in a separate function like this
private void SetItemCheckedFromCode(int index, bool toSet)
{
try
{
_isCodeClick = true;
checkedListBox1.SetItemChecked(index, true);
}
finally
{
_isCodeClick = false;
}
}

MessageBox.Show early in App startup causes app to terminate

As part of my App's startup procedure, it checks data integrity, and if it finds a problem it pops up a message to the user telling them that it might take a while to repair things.
I'm showing the message using MessageBox.Show. Because the data check is done from a worker thread, I'm switching over to the UI thread to make that call, and then setting a ManualResetEvent to tell the worker thread when the user has acknowledged the message.
I kick off the data check/load very early in the app's lifecycle from the constructor in the main Application class, by spinning off a worker thread (using the ThreadPool).
When I run with the debugger, and the message is displayed, the app just waits for input. When I run without the debugger, the app terminates after displaying the dialog for 10 seconds.
That 10 seconds is a big clue - it tells me that the OS thinks the app took too long to initialize (the OS kills apps that take too long to start up).
I think that my MessageBox.Show is blocking the UI thread before the App.RootFrameNavigating has a chance to be invoked.
My questions:
Does my diagnosis sound right?
I'd prefer to kick off my data load early, because it is almost entirely IO, except for this Message Box, and the sooner I can get my Model loaded, the better, but do you normally delay your data load until later in the app lifecycle?
Any other ideas/suggestions? I can't guarantee which page will be the start page, because the app could be resuming to any page. I'm also thinking of having the MessageBox.Show delay itself until the app has initialized, perhaps polling away for a flag set by App.RootFrameNavigating - does that make sense?
I think your problem is a result of kicking off the worker thread in the Application constructor. You should use the appropriate life-cycle event, in this case: PhoneApplicationService.Activated Event
So, the solution I've come up with is to still kick off the data load in a worker-thread from the Application's constructor, but in my PhoneService's class ShowDialog method that I invoke to invoke MessageBox.Show, I check to see if the initial navigation has occurred:
private readonly ManualResetEvent _appInitialized = new ManualResetEvent(false);
public void AppInitialized()
{
_appInitialized.Set();
}
public void ShowDialog(string caption, string text, Action<MessageBoxResult> callback, MessageBoxButton button = MessageBoxButton.OKCancel)
{
_appInitialized.WaitOne();
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
var result = MessageBox.Show(text, caption, button);
if (callback != null)
{
callback(result);
}
});
}
Then in my Application class:
private bool _firstNavigate = true;
private void RootFrameNavigating(object sender, NavigatingCancelEventArgs e)
{
if (_firstNavigate)
{
_firstNavigate = false;
var navigationService = (NavigationService) sender;
navigationService.Navigated += NavigationServiceNavigated;
}
....
private void NavigationServiceNavigated(object sender, NavigationEventArgs e)
{
var navigationService = (NavigationService)sender;
navigationService.Navigated -= NavigationServiceNavigated;
PhoneServices.Current.AppInitialized();
}
Anyone see any issues with this approach? Anyone come up with a better way?

wpf detect open window

In my WPF app (csharp) I have an event handler that when triggered will open a new window (window B) of the application and display some data. However, when the event is triggered again, if the new window (window B) is still open, I don't want to spawn another instance of window B but just update the data being displayed in the current instance. So the question is: How to detect if window B is already and only open if it is not already, otherwise just update the data?
I found the Application.Current.Window collection but somehow that isn't working for me yet. Ideas?
You could create a LoadWindow() method in WindowB that you can call to load (or refresh) the data & that will work regardless of if the window is already open or not. Have it take a delegate to call when this window gets closed:
private Action ParentCallbackOnClose;
public void LoadWindow( Action parentCallbackOnClose ) {
// load the data (set the DataContext or whatever)
ParentCallbackOnClose = parentCallbackOnClose;
// Open the window and activate/bring to the foreground
Show( );
Activate( );
}
and have your window closed event call the close delegate:
private void WindowClosed( object sender, EventArgs e ) {
ParentCallbackOnClose.Invoke( );
}
Now, from your class that opens Window B, have it hold onto that instance it opens, so that if WindowB is already open when someone tries to reload it, it just calls LoadWindow on the existing instance. Something like...
private WindowB WinB;
private void LoadWindowB(Content content)
{
if (WinB == null ){
WinB = new WindowB( );
}
WinB.LoadWindow(content, WindowBClosed);
}
And then you can just have it null out WinB on that close callback so if WinB is closed, then the next time LoadWindowB() is called it will create a new instance of it:
private void WindowBClosed( ){
WinB = null;
}
Since this is the first link Google listed, which posted several years ago, for a solution to check if a Window is already open, I'll post my answer, for others, which I find easier to implement. The ChildWindow is only called from MainWindow so no other Window will need to do any checks.
private void OpenChildWindow()
{
if (this.OwnedWindows.OfType<ChildWindow>().Count() > 0)
{
ChildWindow Win = this.OwnedWindows.OfType<ChildWindow>().First();
Win.Activate();
}
else
{
ChildWindow Win = new ChildWindow();
Win.Owner = this;
Win.Show();
}
}
There is an old school way to do this using an interface. I see this in Java a lot as a way to compensate for not having delegates (correct me if I am wrong). This method will allow you to check if there is a window already open (of any kind). The original response works very well, but you can also do it the following way:
Create the interface
public interface IWindowTracker
{
void WindowIsOpened();
void WindowIsClosed();
}
Implement the interface on the parent (from where you are opening):
public partial class MainWindow : Window, IWindowTracker
In your constructor, accept an object that is of the IwindowTracker interface. Save the instance for future use
IWindowTracker windowTracker;
public ProjectManager(IWindowTracker parentWindowTracker)
{
windowTracker = parentWindowTracker;
InitializeComponent();
}
Setup the calls to the window tracker object
protected override void OnActivated(EventArgs e)
{
windowTracker.WindowIsOpened();
base.OnActivated(e);
}
protected override void OnClosed(EventArgs e)
{
windowTracker.WindowIsClosed();
base.OnClosed(e);
}
and finally implement the IWindowTracker in your parent WPF window
bool windowIsOpen = false;
public void WindowIsOpened()
{
windowIsOpen = true;
}
public void WindowIsClosed()
{
windowIsOpen = false;
}
This will allow you to keep track of if the window is still open and if it is, there is no need to open a new instance of it:
if (!windowIsOpen)
{
remoteProjectManager = new ProjectManager(this);
remoteProjectManager.Show();
}
remoteProjectManager.Focus();
Calling show() on a closed window seems to throw an exception, so my guess is that there is some other way or that if you have closed the window, the window is technically "destroyed"
The nice thing to this is that I can detect if the window is still open and focus on it (so that it comes to the front again).
NOTE: There is a draw back to this, in that in this setup it limits you to opening only one window at a time (assuming that all your windows are implemented like this). In my case, I only ever want to have one window open besides the main window.
You might also want to check if your window is null or not, considering that it probably isn't the only window you will have to open.
edit: oops, my answer is specific to Windows Forms. i just now saw the WPF mention. i'm not sure what the specific code would be for WPF, but i would imagine that it's not all that different conceptually. I think in WPF the property is called IsVisible instead of Visible
You could hold on to the instance of your window (or make it a Singleton) and then when you need to determine if it is visible or not, check it's Visible property.
for example:
if(myWindow.Visible){
myWindow.Hide();
}else{
myWindow.Show();
}
This article it the best I found for passing data between WPF pages. The author used KISS approach to provide a simple solution.

Resources