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
 

 

源碼下載:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM