WPF TextBlock 绑定 换行

最近有个小需求

需要在textblock中换行

 

其实textblock换行有很多写法,比如:

Xaml:

<TextBlock Text="AAAAA&#13;BBBBB" />

<TextBlock Text="AAAAA&#10;BBBBB" />

<TextBlock >AAAAA<LineBreak />BBBBB</TextBlock>

 

CodeBehind:

this.TextBlock1.Text = "AAAAAAA\nBBBBBBBB";

 

绑定的时候其实也很简单,只要用\n就可以了

 

但是有时候情况比较特殊,比如我们这个程序同时还将字符绑定给了一个 MediaElement ,这个时候用\n,则会提示“路径非法字符”…

image

 

 

这下杯具了

想到的简单的方法是处理数据源成一个List<T>,不过在已经乱成一锅粥的代码里貌似改动影响有点大…

在不改动数据源的情况下,只能从TextBlock上想办法了

然后就想到了 附加属性http://msdn.microsoft.com/zh-cn/library/ms749011(v=vs.110).aspx

利用附加属性和转换器,来将TextBlock拆成<Run />和<LineBreak />

 

首先先新建一个转换器,将数据字符串根据分隔符(我设置的分隔符为{n})来拆分成<Run />和<LineBreak />,返回List<Inline>

    public class TextBlockLineBreakConvertor : IValueConverter

    {

        public object Convert(object value, Type targetType,object parameter, CultureInfo culture)

        {

            var inlines = new List<Inline>();

            if (value != null)

            {

                var textblocklines =value.ToString().Split(new string[] { "{n}" }, StringSplitOptions.RemoveEmptyEntries);

                foreach (string line in textblocklines)

                {

                    inlines.Add(new Run() { Text = line });

                    if (textblocklines.ToList().IndexOf(line) < textblocklines.Length - 1)

                    {

                        //加入换行

                        inlines.Add(new LineBreak());

                    }

                }

            }

            return inlines;

        }



        public object ConvertBack(object value, Type targetType,object parameter, CultureInfo culture)

        {

            return value;

        }

    }

 

然后我们新建一个附加属性 InlineList

        public static readonly DependencyProperty TextBlockLineBreakProperty =

            DependencyProperty.RegisterAttached(

                "InlineList",

                typeof(List<Inline>),

                typeof(MainWindow),

                new PropertyMetadata(null, OnLineBreakPropertyChanged));

 

附加属性来将转换器转换成的 List<Inline> 赋值给界面元素

        private static void OnLineBreakPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)

        {

            var tb = obj as TextBlock;

            if (tb != null)

            {

                tb.Inlines.Clear();

                var inlines = e.NewValue as List<Inline>;

                if (inlines != null)

                {

                    inlines.ForEach(inl => tb.Inlines.Add((inl)));

                }

            }

        }

 

然后给 TextBlock 添加上我们建立的附加属性

        public static string GetInlineList(TextBlock element)

        {

            if (element != null)

            {

                return element.GetValue(TextBlockLineBreakProperty) as string;

            }

            else

            {

                return string.Empty;

            }   

        }

        public static void SetInlineList(TextBlock element, string value)

        {

            if (element != null)

            {

                element.SetValue(TextBlockLineBreakProperty, value);

            }

        }
 
最后我们来修改下页面上的数据绑定
<TextBlock local:MainWindow.InlineList="{Binding Str,Converter={StaticResource lineBreakConverter}}"  TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
 
最后添加绑定数据
        private void Window_Loaded(object sender, RoutedEventArgs e)

        {

            List<StringData> l1 = new List<StringData>();

            l1.Add(new StringData() { Str = "AAAAA&#13;{n}BBBBB" });

            l1.Add(new StringData() { Str = "AAAAA&#13;{n}BBBBB" });

            l1.Add(new StringData() { Str = "AAAAA&#13;{n}BBBBB" });

            l1.Add(new StringData() { Str = "AAAAA&#13;{n}BBBBB" });

            ItemsControl1.ItemsSource = l1;

        }
 
最后看看换行效果
image
 

 

源码下载:

你可能感兴趣的:(block)