WPF Automatic FlowDirection

When developing WPF for a BiDi world – the world I live in now – I think it’s important to show the RIGHT paragraph settings for text to user.

The following Converter helps achieve such ability automatically based on text.

using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Data;

namespace DNE.WPF.Converters {

	/// <summary>
	/// This is a Helper Converter.<br/>
	/// It helps determine the <see cref="FlowDirection"/> property, automatically.
	/// </summary>
	public class TextToFlowDirectionConverter : IValueConverter {

		#region IValueConverter Members

		/// <summary>
		/// 
		/// </summary>
		/// <param name="value"></param>
		/// <param name="targetType"></param>
		/// <param name="parameter"></param>
		/// <param name="culture"></param>
		/// <returns></returns>
		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
			string format = parameter as string;
			if (!string.IsNullOrEmpty(format)) {
				return IsRTL(string.Format(culture, format, value)) ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
			}else{
				return IsRTL(string.Format(culture, "{0}", value)) ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="value"></param>
		/// <param name="targetType"></param>
		/// <param name="parameter"></param>
		/// <param name="culture"></param>
		/// <returns></returns>
		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
			return null;
		}

		#endregion

		private bool IsRTL(string input) {
			bool result = false;
			Regex rPersianChars = new Regex("^(?:[^a-z\u060C\u061B\u061F\u0621-\u064A\u064B-\u0652\u0660-\u066D\u0670-\u06F9\uFB50-\uFBB1\uFBD3-\uFD3F\uFDF2\uFDF4\uFDFA-\uFDFB\uFE70-\uFE72\uFE74\uFE76-\uFEFC]*)(?<fachar>[\u060C\u061B\u061F\u0621-\u064A\u064B-\u0652\u0660-\u066D\u0670-\u06F9\uFB50-\uFBB1\uFBD3-\uFD3F\uFDF2\uFDF4\uFDFA-\uFDFB\uFE70-\uFE72\uFE74\uFE76-\uFEFC]+?)");
			MatchCollection mc = rPersianChars.Matches(input);
			if (mc.Count > 0 && mc.Cast<Match>().Any(m => m.Groups["fachar"].Success)) {
				result = true;
			}
			return result;
		}

	}

}

The usage would be really easy:

<Window x:Class="WPFTest.MainWindow"
		xmlns:dneConv="clr-namespace:DNE.WPF.Converters;assembly=DNE.WPF"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:sys="clr-namespace:System;assembly=mscorlib"
		Title="MainWindow" Height="350" Width="525">

 <Window.Resources>
  <dneConv:TextToFlowDirectionConverter x:Key="TextToFlowDirectionConverter"/>
 </Window.Resources>

 <TextBox x:Name="EmailField"  FlowDirection="{Binding Text, Converter={StaticResource TextToFlowDirectionConverter}, RelativeSource={RelativeSource Self}}"/>

</Window>

I hope this helps my fellow Iranian Devs 🙂

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>