C# Winform Dil Desteği
-
Merhaba arkadaşlar uzun süre önce geliştirmeye başladığım çok modüllü bir projem var.
Programın Almanca ve ingilice versiyonlarını çıkarmak istiyoruz.
Buttonların, Label'ların tek tek adını değiştirmek istemiyorum.
hadi bunu bi seferlik yapsam bile ileride elimde üç ayrı versiyon olacak. (Türkçe, Almanca, İngilizce)
Üzerine yaptığım tüm ilaveleri bu üç ayrı proje de de uygulama gibi saçma bir hammallık çıkacak.
Bunun önüne geçmek için bir dil kütüphanesi oluşturup her form load olurken kontrol sağlayıp değiştirme olanağım var mı?
Kaydet = Save
Sil = Delete
Müşterleriler = Customers gibi gibi
bu konuda tecrübesi yada fikri olan arkadaşlardan yardımcı olmalarını talep ediyorum. -
-
resx (resource idi yanlışım yoksa) yada bir json dosyasında değişkenin en, fr, tr vs... değerlerini tutmak olacaktır.
ontedi tarafından 12/Eyl/23 14:41 tarihinde düzenlenmiştir -
ResX ile dil desteği eklemek kolay ama ileride bişeyleri ekleyip değiştirince onları bulup takip etmek çok zor onun için bazı extensionlarla yapıyorlar o işi.
Bu arada ben her dilde her platformda Gettext kullanıyorum ve en sevdiğim librarylerden biri. C# winformsda denemedim ama delphide falan çok bayılarak kullanıyordum
Poedit + gettext
HolyOne tarafından 12/Eyl/23 15:21 tarihinde düzenlenmiştir -
benim bahsetmek istediğim şey form load olurken ekranda yaratılacak nesnelerin text özelliklerine erişip
seçili dil hangi dilse ona göre değer ataması yapıp ekranda oluşturmak gibi.load {
if(secili_dil=='eng')
{nesne.text=dil_kutuphanesi.nesneAd(nesne.text).eng;
}
}
gibi birşey..
-
HolyOne bunu yazdı
ResX ile dil desteği eklemek kolay ama ileride bişeyleri ekleyip değiştirince onları bulup takip etmek çok zor onun için bazı extensionlarla yapıyorlar o işi.
Bu arada ben her dilde her platformda Gettext kullanıyorum ve en sevdiğim librarylerden biri. C# winformsda denemedim ama delphide falan çok bayılarak kullanıyordum
Poedit + gettext
buna bi göz atacağım fakat çalışma mantığı nasıl acaba
önerilen çözümlerin hepsi uğraştırıcı ve ileride karmaşık hale gelebiliyor.. -
7 dakikanı ayır hocam sadece.
https://www.youtube.com/watch?v=08mf72wUOwo
resx kontrolü yönetimi en basiti. yan yana istediğim kadar diz dilleri. 2-3 ile sınırlı kalmana gerek yok.
koca koca projelerde kullanıyoruz aynılarını.
-
baristbt bunu yazdı
7 dakikanı ayır hocam sadece.
https://www.youtube.com/watch?v=08mf72wUOwo
resx kontrolü yönetimi en basiti. yan yana istediğim kadar diz dilleri. 2-3 ile sınırlı kalmana gerek yok.
koca koca projelerde kullanıyoruz aynılarını.
hocam bunları inceledim. benim aradığım farklı birşey.. ama sanırsam istediğim gibi bir çözüm bulamayacağım.
-
Devexpress gridcontrol için aşağıdaki gibi bir çözümle işi kestirmeden bitirmiştik..
public class GridLibrary : GridLocalizer { public override string Language { get { return "Turkish"; } } public override string GetLocalizedString(GridStringId id) { switch (id) { case GridStringId.MenuColumnAutoFilterRowHide: return "Otomatik Filitrelemeyi Gizle"; case GridStringId.MenuColumnRemoveColumn: return "Sütunu Kaldır"; case GridStringId.MenuGroupPanelClearGrouping: return "Gruplamayı Temizle"; case GridStringId.MenuGroupPanelFullCollapse: return "Gruplanan Alanları Kapat"; case GridStringId.MenuGroupPanelFullExpand: return "Gruplanan Alanları Aç"; case GridStringId.MenuColumnAutoFilterRowShow: return "Otomatik Filitrelemeyi Göster"; case GridStringId.MenuColumnClearSorting: return "Sıralamayı Kaldır"; case GridStringId.MenuColumnColumnCustomization: return "Görüntülenecek Alanları Seçin"; case GridStringId.MenuGroupPanelHide: return "Gruplama Panelini Gizle"; case GridStringId.MenuFooterSumFormat: return "Toplam: {0:#,0.00}"; case GridStringId.MenuColumnUnGroup: return "Gruplamayı Kaldır"; case GridStringId.MenuGroupPanelShow: return "Gruplama Panelini Göster"; case GridStringId.MenuColumnFilter: return "Sütunu Filitrele"; case GridStringId.MenuColumnSortAscending: return "A-Z Sırala"; case GridStringId.MenuColumnSortDescending: return "Z-A Sırala"; case GridStringId.MenuColumnShowColumn: return "Sütunu gösterxxx"; case GridStringId.MenuColumnClearFilter: return "Filitrelemeyi Temizle"; case GridStringId.MenuColumnBestFit: return "Kolonu En İyi Boyuta Getir"; case GridStringId.MenuColumnBestFitAllColumns: return "Tüm Kolonları En İyi Boyuta Getir"; case GridStringId.MenuColumnFindFilterShow: return "Grid Üzerinde Arama Yap"; case GridStringId.MenuColumnFindFilterHide: return "Grid Üzerinde Aramayı Gizle"; case GridStringId.MenuColumnExpressionEditor: return "Sütun Düzenleme Editörü"; case GridStringId.FindControlClearButton: return "Temizle"; case GridStringId.FindControlFindButton: return "Bul"; case GridStringId.GridGroupPanelText: return "Gruplanmasını İstediğiniz Sütunu Sürükleyip Bırakın"; case GridStringId.FilterPanelCustomizeButton: return "Sorgulama Editörü"; case GridStringId.GroupSummaryEditorFormCaption: return "Sorgulama Editörü"; case GridStringId.MenuColumnGroup: return "Bu Sütunu Grupla"; case GridStringId.PopupFilterAll: return "Popup Filitrele"; case GridStringId.PopupFilterCustom: return "Hızlı Filitrele"; case GridStringId.MenuColumnFilterEditor: return "Filitreleme Sihirbazı"; case GridStringId.MenuColumnFilterModeDisplayText: return "Filitreleme Sihirbazı"; case GridStringId.FilterBuilderApplyButton: return "Filitrele"; case GridStringId.FilterBuilderCancelButton: return "Vazgeç"; case GridStringId.FilterBuilderCaption: return "Filitreleme Sihirbazı"; case GridStringId.FilterBuilderOkButton: return "Tamam"; case GridStringId.GroupSummaryEditorSummaryCount: return "Otomatik Say"; case GridStringId.MenuColumnGroupSummaryEditor: return "Gruplama Sihirbazı"; case GridStringId.MenuFooterCount: return "Otomatik Say"; case GridStringId.MenuFooterMax: return "Maksimum"; case GridStringId.MenuFooterMin: return "Minimum"; case GridStringId.MenuFooterSum: return "Otomatik Topla"; case GridStringId.MenuFooterAverage: return "Ortalamasını Al"; case GridStringId.MenuFooterNone: return "Hiçbiri"; case GridStringId.MenuColumnCountSummaryTypeDescription: return "Adet"; case GridStringId.MenuFooterAddSummaryItem: return "Yeni Fonksiyon Ekle"; } return base.GetLocalizedString(id); } } -
Evet butonları dinamik olarak oluşturabilirsin. Veritabaninda bir tabloda butonlarin yer alir. Koordinatları, renkleri, boyutlari vs. O tablodaki verileri çekip dinamik olarak butonlari oluşturup ilgili form a ekleyeceksin.
foreach içinde tek tek dolasirsin.
Button b1 = new Button();
b1.Text = textini atarsin
b1.Click = delegeyi atarsın
this.Controls.Add(b1);
Ancak tabi tüm programı bu sekilde yazmak yorucu olur. Tüm program için konuşacak olursak mantıklı olan resources kullanmak. İhtiyaç olan yerlerde elbette dinamik olarak kontrolleri oluşturabilirsin.
-
tr.txt içerisine ;
Save=Kaydet
Delete=Sil
Customers=Müşterilerde.txt içerisine;
Kaydet=Speichern
Sil=Löschen
Müşteriler=Kunden!şeklinde kaydet
private Dictionary<string, string> translations = new Dictionary<string, string>(); private void LoadTranslations(string language) { string[] lines = File.ReadAllLines($"{language}.txt"); foreach (string line in lines) { string[] parts = line.Split('='); if (parts.Length == 2) { string key = parts[0]; string value = parts[1]; translations[key] = value; } } buttonSave.Text = GetTranslation("Save"); buttonDelete.Text = GetTranslation("Delete"); labelCustomers.Text = GetTranslation("Customers"); } private string GetTranslation(string key) { if (translations.TryGetValue(key, out string translation)) { return translation; } return key; }bu şekilde txtde tutabilirsin en kolay bu gibi.
