w8 default tablet settings conflicts with WPF layout - wpf

I have a WPF desktop app. I've gotten reports from W8 users that the code completion window in our app is not aligned correctly. I investigated and found out that its a setting in W8 tablet settings that conflicts with the placement of popups in wpf
Default is right handed and then the code completion popup looks like this
When changed to left handed the code completion popup renders correctly like this
Is there a way to programmaticly force the app to use left handed settings, or ignore it completely so it renders like in w7?
edit: Got an upwote so can update with solution, requires .NET 4.5
private static readonly FieldInfo MenuDropAlignmentField;
static MyWindow()
{
MenuDropAlignmentField = typeof (SystemParameters).GetField("_menuDropAlignment",
BindingFlags.NonPublic | BindingFlags.Static);
System.Diagnostics.Debug.Assert(MenuDropAlignmentField != null);
EnsureStandardPopupAlignment();
SystemParameters.StaticPropertyChanged += (s, e) => EnsureStandardPopupAlignment();
}
private static void EnsureStandardPopupAlignment()
{
if (SystemParameters.MenuDropAlignment && MenuDropAlignmentField != null)
{
MenuDropAlignmentField.SetValue(null, false);
}
}
Full code here
https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.GUI/Shells/MainShellView.xaml.cs

Related

How can the 'fling/flick scrolling' be disabled in CefSharp.Wpf?

Is there a way to disable the 'touch fling scrolling' behaviour in CefSharp.Wpf (or potentially via Cef, Chromium, etc)?
I appreciate it's an unusual request as touch fling scrolling is a great feature. But unfortunately, I need to integrate with a dodgy touch screen hw/driver which works nicely for drag.. but fails miserably when flick scrolling as it consistently 'over scrolls'. e.g. a gentle flick on the screen causes the page content to scroll multiple pages (instead of just a few lines).
There's no CefSharp/Cef/Chromium flag or public method available to cancel Chromium's fling behavior.
Fortunately though, Chromium does internally cancel the fling behavior under certain scenarios (refer Chromium's fling_controller.cc). One such scenario is a user touch down event.
So the trick is to simulate a touch down cancel event pair. Because CefSharp doesn't offer a 'post touch down' event for users to implement the logic (i.e. too much of an edge case), the easiest way is to implement the feature via a derived class.
Here's a complete example (with dependency property binding) in case it helps anyone else look for the same solution..
public class ChromiumWebBrowserEx : ChromiumWebBrowser
{
public static readonly DependencyProperty IsFlingDisabledProperty = DependencyProperty.Register("IsFlingDisabled", typeof(bool), typeof(ChromiumWebBrowserEx));
public bool IsFlingDisabled
{
get => (bool) GetValue(IsFlingDisabledProperty);
set => SetValue(IsFlingDisabledProperty, value);
}
protected override void OnTouchUp(TouchEventArgs e)
{
base.OnTouchUp(e);
if (IsFlingDisabled)
CancelFling(e);
}
private void CancelFling(TouchEventArgs e)
{
// cancel the fling by creating a pseudo touch down followed by a cancellation
var touchPoint = e.GetTouchPoint(this);
if (touchPoint.Action == TouchAction.Up)
{
var touchEvent = new TouchEvent
{
Id = e.TouchDevice.Id,
X = (float) touchPoint.Position.X,
Y = (float) touchPoint.Position.Y,
PointerType = PointerType.Touch,
Modifiers = WpfExtensions.GetModifierKeys(),
Type = TouchEventType.Pressed
};
GetBrowser().GetHost().SendTouchEvent(touchEvent);
touchEvent.Type = TouchEventType.Cancelled;
GetBrowser().GetHost().SendTouchEvent(touchEvent);
}
}
}

Multiple NotifyIcon images in task status area

I have a WPF application I like to keep quietly running when the user closes the main window. I do this using a NotifyIcon in the task status area, and use it as such in my App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
_notifyIcon = new NotifyIcon();
_notifyIcon.DoubleClick += (sender, args) => ShowMainWindow();
_notifyIcon.Icon = Wpf.Properties.Resources.QDrive;
_notifyIcon.Visible = true;
CreateContextMenu();
new Bootstrapper().Run();
Debug.Assert(Current.MainWindow != null, "Application.Current.MainWindow != null");
Current.MainWindow.Closing += MainWindowOnClosing;
}
private void CreateContextMenu()
{
_notifyIcon.ContextMenuStrip = new ContextMenuStrip();
_notifyIcon.ContextMenuStrip.Items.Add("Open Q-Drive...").Click += (sender, args) => ShowMainWindow();
_notifyIcon.ContextMenuStrip.Items.Add("Exit").Click += (sender, args) => ExitApplication();
}
private void ExitApplication()
{
_isExit = true;
Debug.Assert(Current.MainWindow != null, "Application.Current.MainWindow != null");
Current.MainWindow.Close();
_notifyIcon.Visible = false;
_notifyIcon.Dispose();
_notifyIcon = null;
}
Yet after closing and restarting the app a few times while debugging in VS2017, I have multiple icons visible, of which all but the active one vanish on mouse-over. I notice this is a bug with a few other applications I use that I have not developed myself.
How can I prevent this?
NotifyIcon leaves its icon behind if you exit the program without hiding the icon first.
You're hiding it in ExitApplication, of course. I suspect that while debugging, though, you're not always exiting the program by selecting the Exit item on the menu, but simply by stopping Visual Studio. That's why the orphaned icon gets left behind.
This isn't unusual in development, but it won't affect your users unless they use the Task Manager to force an immediate halt to your program.
If it bothers you, though, you could write a global exception handler (something you should probably do anyway) and in that handler you could hide the icon, taking care first to make sure it still exists.
Of course, if you break on exceptions in Visual Studio and you abruptly terminate the program, even that global exception handler won't hide the NotifyIcon.

Controls inside splitter container paint issue on win7 x64 using CAB

I am using CAB and infragistics in winforms application, in a form I have some splitters and user controls with grids, buttons, labels... inside this splitters, when the form is opened in runtime, the user controls are not painted correctly, this problem is known for win7 x64 as described here controls inside Split Container paint issue on Windows 7 and here on this archive link from the Component Factory website cache . The workaround provided in the above topics consist of overriding the OnSizeChanged method :
protected override void OnSizeChanged(EventArgs e)
{
if (Handle != null)
BeginInvoke((MethodInvoker)delegate
{ base.OnSizeChanged(e); });
}
the problem with this solution when using the CAB that this method is called when initializing form components from constructor (InitializeComponent called from constructor ) and OnLoad method is called when Handle property is accessed because it is created if its value is null,
protected override void OnLoad(EventArgs e)
{
_presenter.OnViewReady();
base.OnLoad(e);
}
Here the _presenter is not set yet and its value is null and an axception is thrown.
What can I do for this issue?
Regards.
A simple solution may be to have a field (_isInitilizeCompleted) to indicate if the InitilizeComponent method has completed and modify the OnSizeChanged method to be as follows:
protected override void OnSizeChanged(EventArgs e)
{
if (Handle != null && _isInitilizeCompleted)
BeginInvoke((MethodInvoker)delegate
{ base.OnSizeChanged(e); });
}
I haven't tested but it should work, unless of course OnSizeChanged needs to be called during InitializeComponent.
The idea of using a flag works fine! just the flag test must be done before testing the Handle property :
protected override void OnSizeChanged(EventArgs e)
{
if (_isInitilizeCompleted && Handle != null)
BeginInvoke((MethodInvoker)delegate
{ base.OnSizeChanged(e); });
}

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.

Is it possible to show/hide UserControls within a Silverlight XAP file from JavaScript?

I've created a Silverlight project that produces [something].xap file to package a few silverlight UserControls. I would like to manipulate that .xap file through the use of javascript in the browser to show and hide user controls based upon java script events.
Is it possible to do this?
If so any sample could or links to documentation would be appreciated.
Thanks in advance
Kevin
Here's my solution...not sure if it's the "best-practices" way...comments????
In the App class within my Silverlight application I have the following code:
private Page _page = null;
private void Application_Startup(object sender, StartupEventArgs e)
{
_page = new Page();
this.RootVisual = _page;
HtmlPage.RegisterScriptableObject("App", this);
}
Also to the App class I add a [ScriptableMember] to be called from JavaScript
[ScriptableMember]
public void ShowTeamSearch(Guid ctxId, Guid teamId)
{
_page.ShowTeamSearcher(ctxId, teamId);
}
The Page class is the default one that get's created within the Silverlight Control project, it really doesn't have any UI or logic, it's just used to swap in/out the views.
Login oLogin;
TeamSearcher oSearcher;
public Page()
{
InitializeComponent();
oLogin = new Login();
oSearcher = new TeamSearcher();
oLogin.Visibility = Visibility;
this.LayoutRoot.Children.Add(oLogin);
}
Also a method is added to show/hide the views...this could/will probably get more advanced/robust with animations etc...but this shows the basic idea:
public void ShowTeamSearcher(Guid ctxId, Guid teamId)
{
oSearcher.UserTeamId = teamId;
oSearcher.UserContextId = ctxId;
LayoutRoot.Children.Remove(oLogin);
LayoutRoot.Children.Add(oSearcher);
}
Then to invoke this in the JavaScript after assigning the id of oXaml to the instance of the silverlight host.
var slControl = document.getElementById('oXaml');
slControl.Content.App.ShowTeamSearch(sessionId, teamId);
This seems to work and isn't all that bad of a solution, but there might be something better...thoughts?
Here is a my collections of my links for this subject.
Javascript communication to
Silverlight 2.0
Silverlight
interoperability
Silverlight
and JavaScript Interop Basics

Resources