Вероятно, наиболее очевидным и небедовым способом сделать липкий нижний колонтитул было бы использование новых единиц просмотра css .
Возьмем, к примеру, следующую простую разметку:
header goes here
This page has little content
Если заголовок имеет высоту 80 пикселей, а нижний колонтитул высотой 40 пикселей, мы можем сделать наш липкий нижний колонтитул одним единственное правило в содержимом div:
.content {
min-height: calc(100vh - 120px);
/* 80px header + 40px footer = 120px */
}
Это означает: пусть высота содержимого div должна быть не менее 100% от высоты видового экрана минус комбинированные высоты верхнего и нижнего колонтитула.
Вот и все.
* {
margin:0;
padding:0;
}
header {
background: yellow;
height: 80px;
}
.content {
min-height: calc(100vh - 120px);
/* 80px header + 40px footer = 120px */
background: pink;
}
footer {
height: 40px;
background: aqua;
}
header goes here
This page has little content
... и вот как работает тот же код с большим количеством содержание в содержимом div:
* {
margin:0;
padding:0;
}
header {
background: yellow;
height: 80px;
}
.content {
min-height: calc(100vh - 120px);
/* 80px header + 40px footer = 120px */
background: pink;
}
footer {
height: 40px;
background: aqua;
}
header goes here
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.
NB:
1) Высота верхнего и нижнего колонтитула должна быть известна
2) В старых версиях IE (IE8-) и Android (4.4-) не поддерживаются единицы просмотра. ( caniuse )
3) Когда-то у веб-кита возникла проблема с единицами просмотра в правиле calc. Это действительно исправлено ( см. Здесь ), поэтому там нет проблем. Однако, если вы хотите избежать использования calc по какой-либо причине, вы можете обойти это, используя отрицательные поля и отступы с размером окна -
. Так же:
* {
margin:0;padding:0;
}
header {
background: yellow;
height: 80px;
position:relative;
}
.content {
min-height: 100vh;
background: pink;
margin: -80px 0 -40px;
padding: 80px 0 40px;
box-sizing:border-box;
}
footer {
height: 40px;
background: aqua;
}
header goes here
Lorem ipsum
У меня была похожая проблема. Я провел много времени и не мог решить это. Я был вне времени.
Я не знаю, правильное это решение или нет, но я просто спрятал диалоговое окно входа в систему вместо того, чтобы закрывать его. Он все еще работает
Если вы установите Application.ShutdownMode на OnExplicitShutdown
, можете ли вы избежать включения ShutdownCallback в очередь диспетчера и продолжать делать все, что вы хотите, независимо от окон? Я не проверял это, но кажется потенциальным решением, а также использованием свойства Application.MainWindow , которое можно изменить на лету.
Очень информативный пост, спасибо всем, кто внес вклад. Я использовал плацебо-окно, установив его в главное окно, но не показывало его. Я также установил режим выключения на OnLastWindow. После того, как все диалоговые окна установки были открыты и закрыты, я заменил окно плацебо реальным основным окном и вызвал App.Run (). Это, вероятно, не лучшая практика, но она работает и работает быстро.
Application app = new App();
MainWindow y = new MainWindow();
app.MainWindow = y;
y.WindowStartupLocation = WindowStartupLocation.CenterScreen;
app.ShutdownMode = ShutdownMode.OnLastWindowClose;
//do lots of setup work to include authentication
MainWindow x = new MainWindow(containerdata)
app.MainWindow = x;
App.Run()
Это кажется глючным.
Я обычно ничего не помещаю в Main()
, я позволяю no-arg app.Run()
вызываться и вызывать все, что мне нужно, в методе OnStartup
, но это не изменит поведение, которое вы видите .
Всякий раз, когда мне нужно что-то показать до того, как мое главное окно приложения будет готово к отображению, например, собирать информацию или показывать заставку, я делаю это во втором потоке.
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// show splash
var thread = new Thread(() =>
{
Dispatcher.CurrentDispatcher.BeginInvoke
((Action)(() => new MySplashWindow().Show()));
Dispatcher.Run();
}
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
// run configuration steps
// instantiate and show main window
}
Очевидно, что если вы звоните ShowDialog()
во втором потоке, вам необходимо убедиться, что вы получите ответ, прежде чем показывать главное окно. У него есть преимущество в том, что вы можете запускать другие задачи начальной загрузки, ожидая пользовательского ввода в определенной части; это действительно зависит от того, насколько последовательны ваши различные задачи.
Может быть, это помогает в вашем случае; возможно нет - просто мысль.
По умолчанию ShutdownMode приложения WPF имеет вид OnLastWindowClose. В своем коде вы показываете одно окно, а затем закрываете его. Таким образом, последнее окно закрывается, и приложение закрывается. Затем при закрытии вы показываете другое окно. Поскольку приложение закрывается, окно немедленно закрывается.
Так что все работает так, как вы спроектировали и запрограммировали.
Однако вы хотите сделать что-то другое: окно, которое вы сначала показываете как единственное окно, должно быть «специальным окном», и после его закрытия вы хотите продолжить выполнение, показать свое «главное окно» и затем выйти После закрытия приложения (или всех окон, связанных с приложением).
Самый простой способ: сначала установить режим выключения OnExplicitShutdown, затем, после показа главного окна, установить его в OnLastWindowClose или OnMainWindowClose. В коде:
public static void Main()
{
var app = new App();
app.InitializeComponent();
app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
new DialogWindow().ShowDialog();
var mainWindow = new MainWindow();
app.MainWindow = mainWindow;
app.Run(mainWindow);
// When the window has loaded, it should then set the app.ShutdownMode to what you actually want.
}
РЕДАКТИРОВАТЬ: Я не уверен, что именно вы делаете. Код, который вы дали, не скомпилируется, поскольку при правильном использовании класса приложения WPF (с действием сборки App.xaml в качестве ApplicationDefinition) метод Main уже определен. Если у вас просто есть класс, производный от Application, у вас нет метода InitializeComponent (). Единственный способ получить код для компиляции - вручную изменить действие сборки на Page. Однако в этом случае Application.Current == app.
Итак, происходит следующее:
app.Run(new DialogWindow()); app.Run(new MainWindow());
, у вас было бы исключение при создании MainWindow, так как в этом случае цикл диспетчера работает правильно. Таким образом, он может фактически отключиться, поэтому, когда MainWindow создается, он генерирует исключение, поскольку цикл диспетчера уже отключен. Опять же, без ошибок.
Так что один из способов решить эту проблему - перейти на OnExplicitShutdown. Затем на шаге 4 причина прекращения работы не достигается. Лучше (как в обычном приложении WPF) было бы иметь правильное ApplicationDefinition. Удалите StartupUri из App.xaml и вместо этого обработайте событие Startup:
private void OnStartup(object sender, StartupEventArgs e)
{
this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
new DialogWindow().ShowDialog();
var mainWindow = new MainWindow();
this.ShutdownMode = ShutdownMode.OnLastWindowClose; // or OnMainWindowClose
mainWindow.Show();
}
Так как при закрытии диалогового окна у нас есть OnExplicitShudown, у приложения нет причин начинать закрываться в этой точке. Затем, после создания MainWindow, у нас снова есть окно как главного окна и как одно из окон приложения. Тогда мы можем перейти в режим выключения, который нам действительно нужен, и показать главное окно.