Dispatcher.BeginInvoke is not triggering in WPF - wpf

I am new to WPF and i am trying to create a WPF form and trying to call from another application . I am converting the WPF output as class libarary and calling from another Solution .
There is a .cs file which call this wpf window from code behind using below code .
Thread thre = new thread(()=>
{
mainwindow md = new mainwindow();
md.ShowDialog();
md.Closed+=(s,e)=> md.dispatcher.InvokeShutdown();
Dispatcher.Run()
});
thre.SetApartmentState(ApartmentState.STA);
thre.Start();
I Can able to call my window and all my functionality working excel the dispachter.beginInvoke is not triggering .And i also get Application.Current =null . I am unable to go to if statement in the below code.
Method in window.cs
new Thread(()=>
{
rsult= getItemID("44");
Dispatcher.BeginInvoke( new ThreadStart(()=>{
if(rsult==0)
{}
});
}).Start();
}

ShowDialog() blocks. You should register your event handler, show the window by calling the Show() method and then start the message pump by calling Run():
Thread thre = new thread(()=>
{
mainwindow md = new mainwindow();
md.Closed += (s,e) => md.dispatcher.InvokeShutdown();
md.Show();
Dispatcher.Run()
});
thre.SetApartmentState(ApartmentState.STA);
thre.Start();

Related

To set the owner property for WPF window

I am Working on creating addin for Autodesk Inventor, I have class lib project in that I will show a wpf window on button click, that works great. However, I could not set the owner property for my window.. In my research I came to know that we need to get the parent window object..
If you're not able to get parent window, you can try setting the parent using window handle.
I'm not familiar with Autodesk Inventor and how you create plugin for the application so I don't know if you can get window handle but I guess you could know process id or window caption/title or some other information that can help you get the parent window handle (you should Google how to get window handle). Once you have handle of parent window you can set it as an owner of your window using WindowInteropHelper.
Here's just a sample how to use WindowInteropHelper:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
IntPtr parentWindowHandler = IntPtr.Zero;
// I'll just look for notepad window so I can demonstrate (remember to run notepad before running this sample code :))
foreach (Process pList in Process.GetProcesses())
{
if (pList.MainWindowTitle.Contains("Notepad"))
{
parentWindowHandler = pList.MainWindowHandle;
break;
}
}
var interop = new WindowInteropHelper(this);
interop.EnsureHandle();
// this is it
interop.Owner = parentWindowHandler;
// i'll use this to check if owner is set
// if it's set MainWindow will be shown at the center of notepad window
WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
}
}
I'm just reiterating the example that user1018735 gave. I develop Inventor Add-ins so I modified the code above to make sure I am always working with the correct Inventor session since multiple instances of Inventor can be open at once. I do this by passing my already known application object to my form through the _App parameter; then since the process MainWindowTitle is always the same as the applications caption I match the two.
I'm running this in a WPF Class Library # VB.Net 4.5.1.
Here is a peek at my code that works in Inventor 2014...
Public Sub New(ByVal _App As Inventor.Application)
'This call is required by the designer.
InitializeComponent()
'Find the Inventor Window Handle.
Dim InvWndHnd As IntPtr = IntPtr.Zero
'Search the process list for the matching Inventor application.
For Each pList As Process In Process.GetProcesses()
If pList.MainWindowTitle.Contains(_App.Caption) Then
InvWndHnd = pList.MainWindowHandle
Exit For
End If
Next
Dim InvWndIrp = New WindowInteropHelper(Me)
InvWndIrp.EnsureHandle()
InvWndIrp.Owner = InvWndHnd
...
// Create a window and make this window its owner
Window ownedWindow = new Window();
ownedWindow.Owner = this;
ownedWindow.Show();

WPF application login window not on top

I'm using Prism's MefBootstrapper to initialize my WPF application, as part of this process the Shell window is being initialized.
After Running the MefBootstrapper's Run() method, I'm displaying a login window which connects to a server and in case of a successful connection, the Shell is loaded (from main UI thread).
This login window is running on a new dedicated UI thread, in order not to freeze the progress-bar in this process (connection to the server and especially the Shell loading).
Unfortunately, the login window is not showed on the top and not Focused (even when I'm using: Activate(), TopMost=true, Focus() ).
//UI mode - a new UI thread is initialized
var uiThread = new Thread(() =>
{
var loginWindow = new LoginWindow();
loginWindow.Show();
loginWindow.Activate();
loginWindow.Topmost = true;
loginWindow.Topmost = false;
loginWindow.Focus();
System.Windows.Threading.Dispatcher.Run();
});
uiThread.SetApartmentState(ApartmentState.STA);
uiThread.IsBackground = true;
uiThread.Start();
How can I solve this issue?
Try uiThread.IsBackground = false;
Can you send new instance of LoginWindow to the thread?
uiThread.Start(new LoginWindow());
and then use the loginWindow parameter in the Thread delegate to Show.
I guess that would cause the window to render in the current dispatcher context and would render it on the foreground.
I would create the loginWindow before the ShellWindow is created, just before the end of ConfigureContainer().
That way you won't unnecessarily create views - viewmodels in your regions.
Note, it is important that you don't Close the window before you have shown your ShellWindow (i.e. hide it on successful login) or else the Application will close too.

Getting MainWindow frame from Other Window

So i am in some window2 from this window I tried get frame defined in MainWindow.xaml
by creating a object of Mainwindow and tried to Navigate to a page but program giving " null reference exception unhandeled by user code"
I used:
public Window2()
{
}
myfunction()
{
MainWindow rootwindow = new MainWindow();
rootwindow.myframe.Navigate( new Page1());
}
This is not how you get the frame from another window, you are just creating a new window and try to access something which is not loaded yet as the window you just created has not even been shown yet.
You need a reference to your window, which you could get from Application.Current.MainWindow if you set that accordingly beforehand (e.g. in the App class). Or you could pass a reference to the main window in the constructor of your second window.

InvalidOperationException thrown while trying to open new Window

I have this WPF application in which MainNavigationWindow has registerd events of some other class in its Constructor:
SomeClass obj = new SomeClass();
obj.SomeEvent += new EventHandler(SomeEventHandler);
In the EventHandler method I am trying to show another window, like:
SomeWindow window = new SomeWindow();
window.ShowDialog();
But while creating the new object the above exception is thrown. Can anybody please tell me what can the possible problem and how can I resolve it?
Please note that SomeWindow is derived from System.Window only.
It sounds like the event isn't being raised in the UI thread, and you need to marshal over to the UI thread before creating the window. This is probably as simple as changing your event handler code to:
Action action = () => {
SomeWindow window = new SomeWindow();
window.ShowDialog();
};
Dispatcher.BeginInvoke(action);

WPF image visibility is not changing

I have the following method in my WPF project (.net 4):
private void MyMethod(){
imgMyImage.Visibility = Visibility.Visible;
DoWork();
imgMyImage.Visibility = Visibility.Collapsed;
}
The image is in a DockPanel, and I want it to appear while the "DoWork()" method is being executed, but it does not change state until after the "MyMethod()" method exits. Can someone explain how to make this work correctly?
Thank you for any help.
Your "DoWork" method is blocking the UI thread. Until it completes, nothing in the UI will change (and the UI will remain unresponsive).
A better option is to push the DoWork into a background thread. For example, using the new Task framework in .NET 4, you could write this as:
private void MyMethod()
{
imgMyImage.Visibility = Visibility.Visible;
// Create a background task for your work
var task = Task.Factory.StartNew( () => DoWork() );
// When it completes, have it hide (on the UI thread), imgMyImage element
task.ContinueWith( t => imgMyImage.Visibility = Visibility.Collapsed,
TaskScheduler.FromCurrentSynchronizationContext() );
}

Resources