timheuer / callisto

A control toolkit for Windows 8 XAML applications. Contains some UI controls to make it easier to create Windows UI style apps for the Windows Store in accordance with Windows UI guidelines.
http://timheuer.com/blog/archive/2012/05/31/introducing-callisto-a-xaml-toolkit-for-metro-apps.aspx
Other
338 stars 108 forks source link

CustomDialog shouldn't be sealed #136

Closed stefanolson closed 11 years ago

stefanolson commented 11 years ago

I want to create my own class derived from custom dialog as you would do in WPF derived from window. I will be calling my dialog like this: WelcomePage welcomePage = new WelcomePage {IsOpen = true};

Unfortunately I had to remove the sealed property from custom dialog in order to do this. Would be good if this could be done in the original code base.

The only problem I have found is that when the on-screen keyboard is displayed due to a text box on the custom dialog it scrolls the background window not my custom dialog. Not quite sure how to tell Windows to scroll the custom dialog. Not sure if it is the same issue as this one: https://github.com/timheuer/callisto/issues/132

Stefan

stefanolson commented 11 years ago

I have attempted to hack my way around the problem with the on-screen keyboard and here is the result.

First off, in order to have the keyboard be dismissed when you click in a popup, the pop-up needs to contain a scrollviewer, like this in generic.xaml:

`

    <ScrollViewer IsTabStop="True" HorizontalScrollMode="Disabled" VerticalScrollMode="Disabled" ZoomMode="Disabled">``

Secondly the part name that Tim has used for the root border needs to be changed: private const string PART_ROOT_BORDER = "PART_BannerBorder";

Then in the constructor:

    Unloaded += CustomDialog_Unloaded;

}

void CustomDialog_Unloaded(object sender, RoutedEventArgs e)
{
    Window.Current.SizeChanged -= OnWindowSizeChanged;
    Windows.UI.ViewManagement.InputPane.GetForCurrentView().Showing -= OnInputPaneShowing;
    Windows.UI.ViewManagement.InputPane.GetForCurrentView().Hiding -= OnInputPaneHiding;
}

And at the end of OnApplyTemplate:

Windows.UI.ViewManagement.InputPane.GetForCurrentView().Showing += OnInputPaneShowing;
    Windows.UI.ViewManagement.InputPane.GetForCurrentView().Hiding += OnInputPaneHiding;

    base.OnApplyTemplate();
}

private void OnInputPaneHiding(Windows.UI.ViewManagement.InputPane sender, Windows.UI.ViewManagement.InputPaneVisibilityEventArgs args)
{
    // if the ihm occluded something and we had to move, we need to adjust back
    if (_ihmFocusMoved)
    {
        _rootBorder.VerticalAlignment = VerticalAlignment.Center;
        _ihmFocusMoved = false;
        args.EnsuredFocusedElementInView = true;
    }
}

private void OnInputPaneShowing(Windows.UI.ViewManagement.InputPane sender, Windows.UI.ViewManagement.InputPaneVisibilityEventArgs args)
{
    if (_rootBorder == null) return;

    _rootBorder.VerticalAlignment = VerticalAlignment.Top;
    _ihmFocusMoved = true;
    args.EnsuredFocusedElementInView = true;
}

As said above, this is really simply a hack. All I do is make sure that the whole pop-up is moved to the top. This kind of works in my situation may not work in others. I looked at ways of moving the dialog up, but didn't seem to work very well. Windows doesn't give you a notification of when the focus changes so you never know when you need to move your window into a different position. I'm sure there must be a way to do it, but I just don't know what it is so have resorted to this hack :-) The documentation on the touch keyboard gives no description of how to do this.

Anyway, hope it helps someone.

Stefan

timheuer commented 11 years ago

Unsealed WinRT types aren't allowed and I had envisioned that this eventually be fully WinRT supported, but have had no requests for that level of support, so I'm okay with doing this now.