This article is currently in the process of being translated into Arabic (~53% done).
Application Culture / UICulture
اذا كنت قد تعاملت في بعض الأحيان مع أرقام أو تواريخ في برنامج wpf الخاص بك, مثلا بسبب واحدة من المقالات الموجودة في هذه الدورة التعليمية, قد تكون لاحظت شيئا رائعا: وهو أن الأرقام والتواريخ تعرض تلقائيا بشكل يتوافق مع الشكل المستخدم على جهازك. إذا كنت تعيش في بلد يتحدث اللغة الإنجليزية, لن تلاحظ الفرق, أما لو كنت تعيش في واحد من البلدان الكثيرة حيث تكتب الأرقام أو/و التواريخ بشكل مختلف, فهذا سيكون أمرا رائعا حقا.
و إذا خطر في ذهنك أنه لا يمكن أن يكون هناك العديد من الإختلافات عند تنسيق شيء بسيط مثل التواريخ و الأرقام، فأنا أقترح عليك أن تلقي نظرة على هذا البرنامج البسيط، أين غيرت تنسيق نفس الرقم و التاريخ لتنسجم مع المفضل في الولايات المتحدة، ألمانيا، و السويد:

إذا كما يمكنك مشاهدته هنالك اختلافات في كيفية عرض الأرقام والتواريخ . الخبر الجيد أنه .NET framework يمكن أن تساعدك كثيراً . في الحقيقة هي تفعل ذلك تلقائياً : حيث يتم تهيئة الأرقام و التواريخ طبقاً لإعدادات الكمبيوتر الذي يتم تشغيل البرنامج من خلاله. الخبر السيء أن ذلك التنسيق والتهيئة التلقائية قد يكون ليس كما تريده أن يكون. لكن لا تهتم يمكنك بسهولة تغيير هذه التنسيقات فجميعها تابعة لكلاس CultureInfo , يمكنك معرفة المزيد عن ذلك من خلال الرابط التالي C# Tutorial article on CultureInfo . حاليا دعنا نناقش كيفية تطبيق هذه التقنيات على برنامجك WPF
Ad-hoc formatting
إن كنت تريد ان تنسق جزئية محددة من المعلومات, كمثال. المحتويات الخاصة بـ single Label control, تستطيع ان تفعلها بكل سهولة, وفي وقتها, عن طريق استخدام الصيغة الآتية: ToString() method and the CultureInfo class. على سبيل المثال, في المثال السابق, قد قمت بتطبيق: تنسيق مخصص ومختلف طبقا للثقافة مثل الموجودة بالمثال.
double largeNumber = 123456789.42;
CultureInfo usCulture = new CultureInfo("en-US");
CultureInfo deCulture = new CultureInfo("de-DE");
CultureInfo seCulture = new CultureInfo("sv-SE");
lblNumberUs.Content = largeNumber.ToString("N2", usCulture);
lblNumberDe.Content = largeNumber.ToString("N2", deCulture);
lblNumberSe.Content = largeNumber.ToString("N2", seCulture);
هذا قد يكون مناسب فى بعض الحالات , عندما تريد تنسيق خاص فى بعض المناطق , لكن فى العموم يجب ان تختار بين استخدام التنسيق الاساسى الخاص بالنظام او تنسيق خاص تختاره للبرنامج كله
CurrentCulture & CurrentUICulture
Applying another culture to your WPF application is quite easy. You will, potentially, be dealing with two attributes, found on the CurrentThread property of the Thread class: CurrentCulture and CurrentUICulture. But what's the difference?
إن خاصية CurrentCulture هي التي تتحكم في تنسيق الأرقام والتواريخ، إلخ. تأتي القيمة الافتراضية من نظام تشغيل الحاسوب الذي يُشغّل التطبيق، ويمكن تغييرها بغض النظر عن اللغة المستخدمة. على سبيل المثال، من الشائع جدًا أن يُثبّت شخص مقيم في ألمانيا نظام ويندوز باللغة الإنجليزية كلغة واجهة، مع تفضيله استخدام اللغة الألمانية للأرقام والتواريخ. في مثل هذه الحالة، تكون قيمة خاصية CurrentCulture الافتراضية هي اللغة الألمانية.
إن خاصية CurrentUICultureتُحدد اللغة التي يجب أن تستخدمها الواجهة. علما أنها تكون ذات جدوى فقط إذا كان تطبيقك يدعم لغات متعددة، مثلاً من خلال استخدام ملفات موارد اللغة. حيث تمكنك أيضاً من استخدام ثقافة واحدة للغة (مثل الإنجليزية)، في حين أنك تستخدم ثقافة أخرى (مثل الألمانية) عند إدخال/إخراج الأرقام والتواريخ، إلخ.
Changing the application Culture
مع وضع ذلك في الاعتبار، عليك الآن تحديد ما إذا كنت تريد تغيير CurrentCulture و/أو CurrentUICulture. يمكنك القيام بذلك في أي وقت تريد، ولكن من الأفضل القيام بذلك عند بدء تشغيل تطبيقك، وإلا، فقد يتم توليد بعض المخرجات مسبقًا باستخدام الثقافة الافتراضية، قبل التبديل. إليك مثال نغير فيه الثقافة، بالإضافة إلى UICulture، في حدث Application_Startup() الذي يمكن استخدامه في ملف App.xaml.cs لتطبيق WPF الخاص بك:
private void Application_Startup(object sender, StartupEventArgs e)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
}
Since we use the Thread class as well as the CultureInfo, don't forget to add the required namespaces to your file, if they are not already present:
using System.Threading;
using System.Globalization;
With this in place, numbers and dates will now be formatted according to how they prefer it in German (de-DE). As mentioned, you can leave out the line defining the culture for the UICulture (the last line) if your application doesn't support multiple languages.
Changing the culture during the Application_Startup event, or at the latest in the constructor of your main window, makes most sense, because values that are already generated aren't updated automatically when you change the CurrentCulture property. That doesn't mean that you can't do it though, as illustrated by this next example, which also serves as a fine demonstration of how the output is affected by the CurrentCulture property:
<Window x:Class="WpfTutorialSamples.WPF_Application.ApplicationCultureSwitchSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTutorialSamples.WPF_Application"
mc:Ignorable="d"
Title="ApplicationCultureSwitchSample" Height="200" Width="320">
<StackPanel Margin="20">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label>Number:</Label>
<Label Name="lblNumber" Grid.Column="1" />
<Label Grid.Row="1">Date:</Label>
<Label Name="lblDate" Grid.Row="1" Grid.Column="1" />
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,20">
<Button Tag="en-US" Click="CultureInfoSwitchButton_Click" HorizontalContentAlignment="Stretch">English (US)</Button>
<Button Tag="de-DE" Click="CultureInfoSwitchButton_Click" HorizontalContentAlignment="Stretch" Margin="10,0">German (DE)</Button>
<Button Tag="sv-SE" Click="CultureInfoSwitchButton_Click" HorizontalContentAlignment="Stretch">Swedish (SE)</Button>
</StackPanel>
</StackPanel>
</Window>
using System;
using System.Globalization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
namespace WpfTutorialSamples.WPF_Application
{
public partial class ApplicationCultureSwitchSample : Window
{
public ApplicationCultureSwitchSample()
{
InitializeComponent();
}
private void CultureInfoSwitchButton_Click(object sender, RoutedEventArgs e)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo((sender as Button).Tag.ToString());
lblNumber.Content = (123456789.42d).ToString("N2");
lblDate.Content = DateTime.Now.ToString();
}
}
}
The interesting part is found in the CultureInfoSwitchButton_Click event, where we set CurrentCulture based on which of the buttons were clicked, and then update the two labels containing a number and a date:

Culture & Threads: The DefaultThreadCurrentCulture property
If your application uses more than one thread, you should consider using the DefaultThreadCurrentCulture property. It can be found on the CultureInfo class (introduced in .NET framework version 4.5) and will ensure that not only the current thread, but also future threads will use the same culture. You can use it like this, e.g. in the Application_Startup event:
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("de-DE");
So, will you have to set both the CurrentCulture AND the DefaultThreadCurrentCulture properties? Actually, no - if you have not already changed the CurrentCulture property, setting the DefaultThreadCurrentCulture property will also be applied to the CurrentCulture property. In other words, it makes sense to use the DefaultThreadCurrentCulture instead of CurrentCulture if you plan on using multiple threads in your application - it will take care of all scenarios.
Summary
Dealing with the culture of your WPF application is very important, but fortunately for you, WPF will do a lot of it for you completely out-of-the-box. If you need to change the default behavior, it's quite easy as well, using the CurrentCulture and CurrentUICulture properties, as illustrated in the numerous examples of this article.