WPF ContextMenu click routed to WinForms application - wpf

I am writing a WPF control which is hosted in an Word VSTO AddIn (WinForms). Now I have a problem with the mouse click events on a context menu.
If I click on a context menu item on the left half (the part over the WinForms app), the click goes directly to the WinForms app and my context menu does not receive the event.
If I click the right half of the item (part over the WPF form), everything works as expected.
Can someone out there help me solve this issue?

The answer from the inactive blog is:
Declare a class level dispatcher frame object
System.Windows.Threading.DispatcherFrame _frame;
Subscribe to the GotFocusEvent and LostFocusEvent for the menu:
_menu.AddHandler(System.Windows.UIElement.GotFocusEvent,new RoutedEventHandler(OnGotFocusEvent));
_menu.AddHandler(System.Windows.UIElement.LostFocusEvent, new RoutedEventHandler(OnLostFocusEvent));
Below is the implementation for the event procedures for the GotFocusEvent and LostFocusEvent:
private void OnGotFocusEvent(object sender, RoutedEventArgs e)
{
if (LogicalTreeHelper.GetParent((DependencyObject)e.OriginalSource) == _menu)
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal (DispatcherOperationCallback)delegate(object unused)
{
_frame = new DispatcherFrame();
Dispatcher.PushFrame(_frame);
return null;
}, null);
}
}
private void OnLostFocusEvent(object sender, RoutedEventArgs e)
{
if (LogicalTreeHelper.GetParent((DependencyObject)e.OriginalSource) == _menu)
{
_frame.Continue = false;
}
}
In my case, the if statements weren't needed and I subscribed to the events like this
<EventSetter Event="GotFocus" Handler="contextMenu_GotFocus" />
<EventSetter Event="LostFocus" Handler="contextMenu_LostFocus" />

After some deep research I stumbled upon the following bug:
https://web.archive.org/web/20101211205036/http://connect.microsoft.com:80/VisualStudio/feedback/details/432998/excel-2007-vsto-custom-task-pane-with-wpf-context-menu-has-focus-problems
It's for Excel 2007, but is still valid for other Office products (2007, 2010). I managed to fix my issue using the method described here:
https://web.archive.org/web/20151231010333/http://blogs.msdn.com/b/vsod/archive/2009/12/16/excel-2007-wpf-events-are-not-fired-for-items-that-overlap-excel-ui-for-wpf-context-menus.aspx

Related

how to set focus to a SearchBox control in windows 8.1 store app?

I am developing a windows 8.1 store app. I have a SearchBox control in my app. I want to set focus on it when pointer is pressed on it.
I have tried the following code but it is not working
private void SearchBox_FullView_PointerPressed(object sender, PointerRoutedEventArgs e)
{
SearchBox_FullView.Focus(FocusState.Pointer);
}
How can I solve this problem?
Try this:
private void SearchBox_FullView_PointerPressed(object sender, PointerRoutedEventArgs e)
{
SearchBox_FullView.Focus(FocusState.Programmatic);
}
My problem is solved the problem was in XAML hierarchy that was
<Grid>
<Button/>
<SearchBox/>
<Hub/>
</Grid>
As Hub covers the whole window the Searchbox was visible but not focusable because of the Hub.
I just changed the hierarchy and put the Searchbox after the Hub and it became focusable. And by putting it after the Hub, there was no need for a button left to remove default focus from the SearchBox.

ALT-TAB always activates main window in WPF app with multiple owned windows

On Windows 7, .NET 4.0 I have a problem that can be reproduced by copying the following code into a blank WPF application generated by Visual Studio:
public MainWindow()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
new Window() { Title = "Test", ShowInTaskbar = false, Owner = this }.Show();
}
Run app
Activate secondary window
Alt-Tab to other running application
Use mouse to activate our WPF app in taskbar
Now the WPF app is active again, with the secondary window activated and the main window deactivated, which is the expected (and desired) behavior.
Now do this instead (only step 4 differs):
Run app
Activate secondary window
Alt-Tab to other running application
Alt-Tab back to our WPF app
The WPF app is active again, but now the main window is activated.
Adding this code
private void Application_Activated(object sender, EventArgs e)
{
Windows[1].Activate();
}
to App.xaml.cs does not solve the problem because now in the second case both windows are activated. Also, clicking the secondary window does not deactivate the main window. I have to click the (already activated) main window and the secondary window again to achieve this.
How can I avoid this (only the secondary window should be active in both cases)?
CodeProject actually addresses this issue here, hope this is what you're looking for.
Combine with a post from Tamil Khason and in theory you can override the OnFocus event on a global level so that every time a window is on focus, that becomes the "main window" which will then be the target of ALT+TAB.
based on THIS solution the following code can maybe (not tested jet) also do the trick
protected override void OnStartup(StartupEventArgs e)
{
EventManager.RegisterClassHandler(typeof(Window), Window.LoadedEvent, new RoutedEventHandler(WindowLoaded));
base.OnStartup(e);
}
void WindowLoaded(object sender, RoutedEventArgs e)
{
Window w = sender as Window;
if (w != null)
{
// this part works in my case very well
w.Owner =Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
}
}

The best approach to show/hide windows indpendently

I am a student and am building a C# WPF application. It has three windows:
Sign in window
Create account window
and Main application window.
I uploaded a figure to show the type of navigation I am trying to implement:
I do not think it is correct to make a window show up/hide inside the close/load event of another window.
Can someone show me the right way to implement this navigation?
Also, is it a good practice to make the three windows private properties of the application class?
The last window has a frame control to support page navigation. Again, is it better to make the three pages private properties of MainWindow application?
I am sorry if this is so obvious or easy to do.
Thanks
I would not have the three windows as properties of the application. I'd instanciate a copy of the sign-in window and use that as my central point of control.
When the user logs in, hide the sign in window, show a new main window and add a hook on the main windows Closed event.
e.g
if (logonSuccess)
{
var mainWindow = new MainWindow();
mainWindow.Closed += ReshowSignupWindow;
}
I'd also have the sign-in window do the same for the create account window. Thus, I'd have the create account window return to the signup window which would either reshow itself or start the main window if an account was created.
e.g.:
// In sign-in window, handle the create window being closed
private void CreateWindowClosedHandler(object sender, EventArgs e)
{
if (accountCreatedOK)
{
ShowMainWindow();
}
else
{
ReshowSignupWindow();
}
}
I'd probably look at having the create account window shown as a dialog window via a call to ShowDialog().
Hope that helps...
Something like this code might do it (untested, I just typed it in visual studio to autoformat the code)
The XAML is for the Login Dialog. The RegistrationDialog should be similar, except for the button and handler for the registration Button.
<Window x:Class="WpfApplication1.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="LoginWindow">
<StackPanel>
<Button IsDefault="True" Content="Submit" Click="SubmitButton_Click"/>
<Button IsCancel="True" Content="Cancel" />
<Button Content="CreateAccount" Click="CreateAccountButton_Click"/>
</StackPanel>
</Window>
//Handler of LoginWindow and RegistrationWindow
private void SubmitButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
//Handler of LoginWindow only
private void CreateAccountButton_Click(object sender, RoutedEventArgs e)
{
this.IsCreatingAccount = true;
this.DialogResult = false;
}
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
bool isCanceled;
while (loginWin.ShowDialog() == false && !isCanceled)
{
if (loginWin.IsAccountCreationRequested)
{
if (registrationWin.ShowDialog())
{
isCanceled = true;
}
else
{
loginWin.IsAccountCreationRequested = false;
}
}
else
{
isCanceled = true;
}
}
if (loginWin.DialogResult) MainWindow.Show();
}
}
I am currently working on a Silverlight Application which is more or less similar to your application. What i feel is your can have 2 xaml controls(one for Login and other for your main application). For create account, you can use a child window which will be called from login control. And use a TabControl in your main application which will hold your other 3 xaml controls(Page1.xaml, Page2.xaml and Page3.xaml). Feel free to ask if you have any issues.
Dont forget to mark my reply as answer if it solves your problem.
I suggest you to follow the pattern. Your logic looks tightly binding with UI(user Interface) and logics.
The best pattern i like is for WPF or Silverlight is MVVM(Model View View Model). There are lot of Examples available in google for MVVM.
Just put a glance in anyone MVVM example you will be clear in developing WPF or Silverlight app.
some links are below,
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
http://www.c-sharpcorner.com/UploadFile/raj1979/simple-mvvm-pattern-in-wpf/
http://www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute

Navigation in Silverlight 5

I want to navigate to new page on the click event of Next button. Suppose my current page is "FirstTestPage.xaml" and want to go on the page "SecondTestPage.xaml" on click on nextButton_Click Event
private void RadButton_Click(object sender, RoutedEventArgs e)
{
///CODE HERE
}
And also want the back button which transfer me to FirstTestPage.xaml.
Thank You
Please see my answer to the question: Making a Wizard in Silverlight + Xaml
to quote it: "I would suggest looking into the Silverlight Navigation Framework. It allows you to use "urls" to navigate between "pages" (which are your XAML user controls). It also also users to use the back and forth buttons in the browser, which may or may not be something you want to allow.
There is a VS 2010 template when you choose New Project, Silverlight, "Silverlight Navigation Application" that will help get you started."
You can also use a border or panel in the Xaml and change the content of that. Here's an example using border.
XAML
<Grid>
<Border x:Name="contentBorder" />
</Grid>
Code Behind:
private void RadButton_Click(object sender, RoutedEventArgs e)
{
this.contentBorder.Child = new SecondTestPage();
}
If you want to get fancy and have the Telerik controls (which I assume from your RadButton example) check out their transition control: http://demos.telerik.com/silverlight/#TransitionControl/FirstLook

WPF ComboBox DropDown part appears in the wrong place

I put several ComboBoxes on a XAML window. When I expand any of them, the DropDown part appears on the upper left corner of the screen.
I use Visual Studio 2008 C# Express. I don't remember this phenomenon when I used Visual Studio 2008 (Trial Version), though I use the same FrameWork (3.5).
It seems to be a bug.
Workaround:
Use Window.Show() instead with a custom logic to simulate the ShowDialog() behavior.
This appears to be a bug in WPF. In my case, I was trying to open a window in the Loaded event of another window. To get around this, I set a timer up to fire, then used a delegate to open the window (cannot open the window in a timer event because the calling thread that opens a window must be STA).
Edit - timer isn't necessary - didn't see the answer above just queue it on the dispatcher...
private delegate void DelegateOpenWindow();
private DelegateOpenWindow m_DelegateOpenWindow;
private Timer loginTimer = new Timer(200);
private void MainWindow1_Loaded(object sender, RoutedEventArgs e)
{
// create delegate used for asynchronous call
m_DelegateOpenWindow= new DelegateOpenWindow(this.OpenWindow);
// start a timer to fire off the open window.
loginTimer.Elapsed += loginTimer_Elapsed;
loginTimer.Enabled = true;
}
void loginTimer_Elapsed(object sender, ElapsedEventArgs e)
{
loginTimer.Enabled = false;
this.Dispatcher.BeginInvoke(m_DelegateOpenWindow);
}
void OpenWindow()
{
MyWindow w = new MyWindow();
w.Owner = this;
w.ShowDialog();
}
I started observing this (and other strange behavioral quirks) yesterday when I tried to "tweak" window sizes, shapes, colors, and invoke a log-on dialog from the Window.Loaded event handler. I had been doing this just fine in each of a dozen+ individual "MVVM" pattern apps. Yesterday, I decided to move this from each app's code behind into a consolidated code-behind base class, since the pre-processing had become common in all those apps. When I did, the drop-downs in two ComboBoxes in the log-in dialog suddenly appeared in the upper left corner of my screen. I seem to have "solved" it by using the following technique (your mileage may vary):
protected void WindowBaseLoadedHandler(object sender, RoutedEventArgs e)
{
...non-essential lines of code removed...
if (DataContext != null)
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
/*----------------------------------------------------------------------
* Do we have a View Model? If so, perform standard VM Initialization...
*---------------------------------------------------------------------*/
this.IsEnabled = false;
LoginDlg loginDlg = new LoginDlg();
loginDlg.ShowDialog();
if (!loginDlg.Success)
{
/*-----------------------------------
* Log on failed -- terminate app...
*----------------------------------*/
...termination logic removed...
}
this.IsEnabled = true;
}));
}
WindowBaseLoadedHandler is the Loaded event handler. LoginDlg is a WPF app with a dialog containing two ComboBoxes.
Recap: After I consolidated the code into the Loaded event handler of the base class the ComboBox's drop down lists appeared in the upper left corner of my screen. Once I wrapped the logic into the Dispatcher.BeginInvoke call, the appropriate ComboBox behavior returned with lists below the current item.
I suspect WPF needs the application to return from the Loaded event to complete the layout system's initialization. That doesn't fully explain why it worked before, but I'll have to queue up my desire to hunt that "why" down for some rainy day in the future and celebrate overcoming the latest obstacle for today.
In any event, I hope someone finds this of use.
I'm using the latest .Net 4.5 and WPF framework and I still have this problem. One thing I noticed is that it only happen when there's an attached debugger. When the debugger is not attached, everything works fine.
I had the same problem on Visual Studio 2019.
Using window.Show() can help but it can ruin your design.
The solution is to open the window asynchronously.
var yourDialog= new YourDialog();
yourDialog.Owner = this;
TaskCompletionSource<bool?> completion = new TaskCompletionSource<bool?>();
this.Dispatcher.BeginInvoke(new Action(() =>
completion.SetResult(yourDialog.ShowDialog())));
bool? result = await completion.Task;
You can also create a more elegant solution by making the extension method:
public static class AsyncWindowExtension
{
public static Task<bool?> ShowDialogAsync(this Window self)
{
if (self == null) throw new ArgumentNullException("self");
TaskCompletionSource<bool?> completion = new TaskCompletionSource<bool?>();
self.Dispatcher.BeginInvoke(new Action(() => completion.SetResult(self.ShowDialog())));
return completion.Task;
}
}
And you can use it like this:
await dlgReview.ShowDialogAsync();
It’s a bug in WPF (not the only one, I'm afraid). It happened when I opened another window in the Loaded Event, something like:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Window selectionWindow = new SelectionWindow();
bool? result = selectionWindow.ShowDialog();
if (result == true)
RecordChanged();
}
I already found a workabout.

Resources