Другое решение, помимо уже упомянутых ondes (с использованием layout
или par(xpd=TRUE)
), состоит в том, чтобы наложить ваш график на прозрачный график на всем устройстве, а затем добавить к нему легенду.
трюк состоит в том, чтобы наложить (пустой) график на всю область построения и добавить к этому легенду. Мы можем использовать опцию par(fig=...)
. Сначала мы инструктируем R создать новый график по всему устройству построения:
par(fig=c(0, 1, 0, 1), oma=c(0, 0, 0, 0), mar=c(0, 0, 0, 0), new=TRUE)
Настройка oma
и mar
необходима, так как мы хотим, чтобы внутренняя часть сюжета охватывала все устройство. new=TRUE
необходимо, чтобы R не запускал новое устройство. Затем мы можем добавить пустой сюжет:
plot(0, 0, type='n', bty='n', xaxt='n', yaxt='n')
И мы готовы добавить легенду:
legend("bottomright", ...)
добавит легенду в нижнюю правую часть устройства. Аналогично, мы можем добавить легенду на верхний или правый край. Единственное, что нам нужно, это убедиться, что край исходного сюжета достаточно велик, чтобы разместить легенду.
Включение всего этого в функцию;
add_legend <- function(...) {
opar <- par(fig=c(0, 1, 0, 1), oma=c(0, 0, 0, 0),
mar=c(0, 0, 0, 0), new=TRUE)
on.exit(par(opar))
plot(0, 0, type='n', bty='n', xaxt='n', yaxt='n')
legend(...)
}
И пример. Сначала создайте сюжет, чтобы у нас было достаточно места внизу, чтобы добавить легенду:
par(mar = c(5, 4, 1.4, 0.2))
plot(rnorm(50), rnorm(50), col=c("steelblue", "indianred"), pch=20)
Затем добавьте легенду
add_legend("topright", legend=c("Foo", "Bar"), pch=20,
col=c("steelblue", "indianred"),
horiz=TRUE, bty='n', cex=0.8)
В результате:
[/g0]
Мы в настоящее время используем WindowsFormsHost в нашем программном обеспечении для хостинга управления WinForms DataGridView, и у нас не было настоящих проблем с ним. Несколько вещей не упустить, хотя:
Первыми являются ограничения воздушного пространства. В сущности это означает, что содержание WinForms всегда появляется сверху содержания WPF. Таким образом, если Вы будете использовать WPF adorners, то они, будет казаться, будут "обрезаны", если они подбросят ударом против региона WinForms в Вашем приложении.
Второе - то, что, потому что они используют ресурсы Windows, необходимо управлять временем жизни компонентов WinForms более тщательно. В отличие от компонентов WPF, средства управления WinForms ожидают быть Расположенными, когда они будут закончены с. Это делает это хитрым для включения их в чистое представление XAML.
Последняя вещь состоит в том, что средства управления WinForms, кажется, не изменяют размер так же гладко как остальная часть дисплея WPF: они имеют тенденцию привязываться к их новому размеру, после того как Вы закончили вносить корректировку.
Одна проблема, с которой я столкнулся, состоит в том, что встроенный Приобретают контроль Формами, не участвуют ни в ком, преобразовывают операции, относился к их контейнеру WPF. Это приводит к визуальным эффектам высвечивания и встроенному управлению, появляющемуся в несоответствующем месте. Я работал вокруг этого путем привязки видимости Хоста Windows Forms состояния анимации ее контейнера WPF, так, чтобы встроенное управление было скрыто до завершенной анимации, как ниже.
<WindowsFormsHost Grid.Row="1" Grid.Column="1" Margin="8,0,0,0"
Visibility="{Binding ActualHeight, RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType=UserControl},
Converter={StaticResource WinFormsControlVisibilityConverter}}" >
<winforms:DateTimePicker x:Name="datepickerOrderExpected" Width="140"
Format="Custom" CustomFormat="M/dd/yy h:mm tt"
ValueChanged="OnEditDateTimeOrderExpected" />
</WindowsFormsHost>
Я разместил средства управления WPF в WinForms и наоборот без проблем. Хотя, я протестировал бы такие сценарии экстенсивно, потому что трудно предсказать, как сложное управление будет вести себя.
Действительно отметьте отсутствие WPF Application
возразите при хостинге в Winforms. Это может привести к проблемам, если Вы берете существующий компонент WPF и размещаете его в Winforms, так как поиски ресурса и подобные никогда не будут смотреть в области действия приложения. Можно создать собственное Application
возразите, является ли это проблема.
Как @Kent Boogaart упомянул, я столкнулся с ситуацией, где приложение WPF, размещенное в WinForms, не имеет Объекта приложения WPF (т.е. Приложение. Текущий). Это может вызвать много проблем, таких как Диспетчеры, не вызывающие потоки назад к потоку UI. Это только применялось бы, если Вы размещаете в WinForms, не наоборот.
У меня также были странные проблемы с модальными диалоговыми окнами, ведущими себя странно (т.е. вызовы ShowModal). Я предполагаю, что это вызвано тем, что в WinForms каждое управление имеет свой собственный дескриптор Win32 в то время как в WPF, существует только один дескриптор для всего Окна.
Независимо от того, что Вы делаете, тест :)
Можно решить проблему Воздушного пространства при помощи .net 3.5 SP1:
Эти типы ограничений воздушного пространства представляют огромное ограничение в платформе, как WPF, где состав элемента используется для создания очень богатых пользовательских событий. С решением D3DImage больше не присутствуют эти ограничения!
Посмотрите введение в D3DImage.