Semua ContainerControls harus disetel sama AutoScaleMode = Font
. (Font akan menangani perubahan DPI dan perubahan pada pengaturan ukuran font sistem; DPI hanya akan menangani perubahan DPI, bukan perubahan pada pengaturan ukuran font sistem.)
Semua ContainerControls juga harus diset dengan sama AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
, dengan asumsi 96dpi (lihat butir berikutnya) dan Font default MS Sans Serif (lihat dua peluru di bawah). Itu ditambahkan secara otomatis oleh desainer berdasarkan DPI Anda membuka desainer di ... tetapi hilang dari banyak file desainer tertua kami. Mungkin Visual Studio .NET (versi sebelum VS 2005) tidak menambahkan itu dengan benar.
Apakah semua perancang Anda bekerja di 96dpi (kami mungkin dapat beralih ke 120dpi; tetapi kebijaksanaan di internet mengatakan untuk tetap berpegang pada 96dpi; eksperimen dilakukan di sana; secara desain, tidak masalah karena hanya mengubah AutoScaleDimensions
baris yang sisipan desainer). Untuk mengatur Visual Studio agar dijalankan pada 96dpi virtual pada tampilan resolusi tinggi, temukan file .exe, klik kanan untuk mengedit properti, dan di bawah Kompatibilitas pilih "Ganti perilaku penskalaan DPI tinggi. Penskalaan dilakukan oleh: Sistem".
Pastikan Anda tidak pernah mengatur Font di level kontainer ... hanya di kontrol daun ATAU di konstruktor Form paling dasar Anda jika Anda ingin Font default aplikasi-lebar selain MS Sans Serif. (Mengatur Font pada Wadah tampaknya mematikan penskalaan otomatis wadah itu karena secara alfabet muncul setelah pengaturan pengaturan AutoScaleMode dan AutoScaleDimensions.) Perhatikan bahwa jika Anda mengubah Font di konstruktor Form paling dasar Anda, itu akan menyebabkan Dimensi AutoScale Anda untuk menghitung secara berbeda dari 6x13; khususnya, jika Anda mengubah ke Segoe UI (font default Win 10), maka itu akan menjadi 7x15 ... Anda harus menyentuh setiap Formulir di Designer sehingga dapat menghitung ulang semua dimensi dalam file .designer itu, termasuk itu AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
.
JANGAN gunakan Jangkar Right
atau Bottom
berlabuh ke UserControl ... posisinya tidak akan skala otomatis; sebagai gantinya, letakkan Panel atau wadah lain ke dalam UserControl Anda dan Jangkar Kontrol Anda yang lain ke Panel itu; memiliki penggunaan Panel Dock Right
, Bottom
atau Fill
di UserControl Anda.
Hanya kontrol di daftar Kontrol ketika ResumeLayout
pada akhir InitializeComponent
dipanggil akan diskalakan otomatis ... jika Anda menambahkan kontrol secara dinamis, maka Anda harus SuspendLayout();
AutoScaleDimensions = new SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
ResumeLayout();
menggunakan kontrol itu sebelum menambahkannya. Dan posisi Anda juga perlu disesuaikan jika Anda tidak menggunakan mode Dock atau Layout Manager suka FlowLayoutPanel
atau TableLayoutPanel
.
Kelas-kelas dasar yang diturunkan ContainerControl
harus dibiarkan AutoScaleMode
disetel ke Inherit
(nilai default yang ditetapkan di kelas ContainerControl
; tetapi BUKAN set standar oleh perancang). Jika Anda mengaturnya ke hal lain, dan kemudian kelas turunan Anda mencoba mengaturnya ke Font (sebagaimana mestinya), maka tindakan pengaturan yang Font
akan menghapus pengaturan desainer AutoScaleDimensions
, menghasilkan benar-benar mematikan penskalaan otomatis! (Pedoman ini dikombinasikan dengan yang sebelumnya berarti Anda tidak akan pernah dapat membuat kelas dasar dalam desainer ... semua kelas harus dirancang sebagai kelas dasar atau sebagai kelas daun!)
Hindari menggunakan Form.MaxSize
statis / di Designer. MinSize
dan MaxSize
pada Formulir tidak skala sebanyak yang lainnya. Jadi, jika Anda melakukan semua pekerjaan Anda dalam 96dpi, maka ketika pada DPI yang lebih tinggi Anda MinSize
tidak akan menimbulkan masalah, tetapi mungkin tidak seketat yang Anda harapkan, tetapi Anda MaxSize
dapat membatasi penskalaan Ukuran Anda, yang dapat menyebabkan masalah. Jika Anda mau MinSize == Size == MaxSize
, jangan lakukan itu di Designer ... lakukan itu di konstruktor Anda atau OnLoad
timpa ... atur keduanya MinSize
dan MaxSize
ke Ukuran Anda dengan skala yang benar.
Semua Kontrol pada tertentu Panel
atau Container
harus menggunakan Penahan atau Docking. Jika Anda mencampurnya, penskalaan otomatis yang dilakukan olehnya Panel
akan sering bertingkah aneh dengan cara yang aneh.
Ketika melakukan penskalaan otomatis, ia akan mencoba untuk menskala Formulir keseluruhan ... namun, jika dalam proses itu ia berjalan ke batas atas ukuran layar, itu adalah batas keras yang kemudian dapat dikacaukan (klip) scaling. Oleh karena itu, Anda harus memastikan semua Formulir di Perancang dengan ukuran 100% / 96dpi berukuran tidak lebih besar dari 1024x720 (yang sesuai dengan 150% pada layar 1080p atau 300% yang merupakan nilai yang disarankan Windows pada layar 4K). Tetapi Anda perlu mengurangi untuk bar judul / caption Win10 raksasa ... jadi lebih seperti 1000x680 Ukuran maks ... yang pada perancang akan seperti 994x642 ClientSize. (Jadi, Anda dapat melakukan Referensi FindAll di ClientSize untuk menemukan pelanggar.)
NumericUpDown
tidak skala denganMargin
baik juga. Tampaknya margin diskalakan dua kali. Jika saya skala kembali, itu terlihat bagus.AutoScaleMode = Font
tidak bekerja dengan baik untuk pengguna yang menggunakan font yang sangat besar dan dengan di Ubuntu. Kami lebih sukaAutoScaleMode = DPI
Pengalaman saya cukup berbeda dengan jawaban terpilih saat ini. Dengan melangkah melalui .NET framework code dan membaca kode sumber referensi, saya menyimpulkan bahwa semuanya sudah ada untuk penskalaan otomatis berfungsi, dan hanya ada masalah halus di suatu tempat yang mengacaukannya. Ternyata ini benar.
Jika Anda membuat tata letak yang dapat dipantulkan dengan benar / otomatis, maka hampir semuanya berfungsi persis seperti seharusnya, secara otomatis, dengan pengaturan default yang digunakan oleh Visual Studio (yaitu, AutoSizeMode = Font pada formulir induk, dan Mewarisi pada yang lain).
Satu-satunya gotcha adalah jika Anda telah mengatur properti Font pada formulir di perancang. Kode yang dihasilkan akan mengurutkan penugasan berdasarkan abjad, yang berarti bahwa
AutoScaleDimensions
akan ditetapkan sebelumnyaFont
. Sayangnya, ini benar-benar memecah logika penskalaan otomatis WinForms.Cara mengatasinya sederhana. Entah tidak menyetel
Font
properti di desainer sama sekali (atur di konstruktor formulir Anda), atau atur ulang secara manual tugas-tugas ini (tetapi kemudian Anda harus terus melakukan ini setiap kali Anda mengedit formulir di desainer). Voila, penskalaan yang hampir sempurna dan otomatis sepenuhnya dengan kerumitan minimal. Bahkan ukuran formulir diskalakan dengan benar.Saya akan membuat daftar masalah yang diketahui di sini saat saya menjumpainya:
TableLayoutPanel
menghitung margin kontrol secara salah . Tidak ada cara kerja yang diketahui untuk menghindari margin dan bantalan sama sekali - atau menghindari panel tata letak meja bersarang.sumber
Font
dalam desainer: Suatu pemikiran muncul di pikiran: pergi ke depan dan atur font di desainer, sehingga Anda dapat merancang dengan font yang diinginkan. LALU di konstruktor, setelah tata letak, baca properti font itu dan atur kembali nilai yang sama? Atau mungkin hanya meminta tata letak untuk dilakukan lagi? [Peringatan: Saya belum punya alasan untuk menguji pendekatan ini.] Atau sesuai jawaban Knowleech , dalam perancang tentukan dalam piksel (jadi perancang Visual Studio tidak akan mengubah skala pada monitor DPI tinggi), dan dalam kode baca nilai itu, konversi dari piksel ke poin (untuk mendapatkan penskalaan yang benar).AutoScaleDimensions
tidak diatur kenew SizeF(6F, 13F)
seperti yang direkomendasikan dalam jawaban teratas. Ternyata dalam setiap contoh, properti Font formulir telah disetel (tidak bawaan). Tampaknya ketikaAutoScaleMode = Font
, kemudianAutoScaleDimensions
dihitung berdasarkan properti font formulir. Selain itu, pengaturan Penskalaan pada Panel Kontrol Windows tampaknya memiliki pengaruhAutoScaleDimensions
.Targetkan Aplikasi Anda untuk .Net Framework 4.7 dan jalankan di bawah Windows 10 v1703 (Creators Update Build 15063). Dengan .Net 4.7 di bawah Windows 10 (v1703), MS membuat banyak peningkatan DPI .
Untuk mendukungnya, tambahkan manifes aplikasi ke aplikasi Anda dan beri tanda bahwa aplikasi Anda mendukung Windows 10:
Selanjutnya, tambahkan
app.config
dan nyatakan aplikasi Per Monitor Sadar. Ini SEKARANG dilakukan di app.config dan BUKAN di manifes seperti sebelumnya!Ini PerMonitorV2 baru sejak Windows 10 Kreator Update:
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
Sekarang Anda dapat berlangganan 3 acara baru untuk mendapat pemberitahuan tentang perubahan DPI:
Anda juga memiliki 3 metode pembantu tentang penanganan / penskalaan DPI:
Control.LogicalToDeviceUnits , yang mengubah nilai dari logis ke piksel perangkat.
Control.ScaleBitmapLogicalToDevice , yang mengubah skala gambar bitmap ke DPI logis untuk suatu perangkat.
Control.DeviceDpi , yang mengembalikan DPI untuk perangkat saat ini.
Jika Anda masih melihat masalah, Anda dapat menyisih dari peningkatan DPI melalui entri app.config .
Jika Anda tidak memiliki akses ke kode sumber, Anda dapat pergi ke properti aplikasi di Windows Explorer, pergi ke kompatibilitas dan pilih
System (Enhanced)
yang mengaktifkan penskalaan GDI untuk juga meningkatkan penanganan DPI:
Lakukan semua langkah itu dan Anda harus mendapatkan pengalaman DPI yang lebih baik untuk aplikasi WinForms. Tapi ingat, Anda harus menargetkan aplikasi Anda untuk .net 4.7 dan membutuhkan setidaknya Windows 10 Build 15063 (Pembaruan Pembuat). Di Pembaruan Windows 10 1709 berikutnya, kita mungkin mendapatkan lebih banyak perbaikan.
sumber
Panduan yang saya tulis di tempat kerja:
sumber
Saya merasa sangat sulit untuk membuat WinForms bermain bagus dengan DPI tinggi. Jadi, saya menulis metode VB.NET untuk mengganti perilaku formulir:
sumber
Saya baru-baru ini menemukan masalah ini, terutama dalam kombinasi dengan Visual Studio rescaling ketika editor dibuka pada sistem dpi tinggi. Saya menemukan itu yang terbaik untuk menjaga
AutoScaleMode = Font
, tetapi untuk mengatur Bentuk Font untuk font default, tetapi menentukan ukuran dalam pixel , tidak titik, yaitu:Font = MS Sans; 11px
. Dalam kode, saya kemudian mengatur ulang font ke default:Font = SystemFonts.DefaultFont
dan semuanya baik-baik saja.Hanya dua sen saya. Saya pikir saya berbagi, karena “menjaga AutoScaleMode = Font” , dan “Mengatur ukuran font dalam pixel untuk Perancang” adalah sesuatu yang tidak saya temukan di internet.
Saya memiliki beberapa rincian lebih lanjut di Blog saya: http://www.sgrottel.de/?p=1581&lang=en
sumber
Selain jangkar tidak berfungsi dengan baik: Saya akan melangkah lebih jauh dan mengatakan bahwa penentuan posisi yang tepat (alias, menggunakan properti Lokasi) tidak berfungsi dengan baik dengan penskalaan font. Saya harus mengatasi masalah ini dalam dua proyek yang berbeda. Di keduanya, kami harus mengubah posisi semua kontrol WinForms untuk menggunakan TableLayoutPanel dan FlowLayoutPanel. Menggunakan properti Dock (biasanya diatur ke Isi) di dalam TableLayoutPanel bekerja dengan sangat baik dan skala baik dengan font sistem DPI.
sumber