Auf Codekicker wurde eine Frage gestellt, die mich doch etwas mehr an Zeit gekostet hat, als ich gedacht habe. Bei der Fragestellung ging es darum, einen gebundenen Text innerhalb der Zelle zu formatieren. Ein String in der Zelle sollte so formatiert werden, dass bei der Übergabe von Keywords, diese Fett dargestellt werden sollen. (siehe Bild am Ende des Artikels)
Mein erster Gedanke war, dass ich in einem Converter die Parameter innerhalb des Strings suche, diese dann mit der Run-Klasse “ummantle” und zurückgebe. Doch leider war das nicht ganz so trivial, wie ich zuerst dachte.
Nun denn, ich hab’s doch hinbekommen, wie, dass möchte ich im folgenden Artikel zeigen.
Mein Converter ist zur ersten Hälfte eigentlich so geworden, wie ich es ursprünglich vorhatte. Anstelle aber einen String zurück zugeben, musste ich den formatierten Text als XAML in einen StringBuilder einlesen und diesen über den XmlReader zu einem TextBlock-Control erstellen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string s = (string)value; //Suchwörter ermitteln List<string> keywords = ((string)parameter).Split(new char[] { ' ' }).ToList(); //Suchwörter replacen keywords.ForEach(k => s = s.Replace(k, String.Format("<Bold>{0}</Bold>", k))); //TextBlock bauen StringReader sr = new StringReader(string.Format(@"<TextBlock xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>{0}</TextBlock>", s)); XmlReader reader = XmlReader.Create(sr); return ((TextBlock)XamlReader.Load(reader)).Inlines.ToList<Inline>(); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } |
Den TextBlock gebe ich nun zurück und stelle diesen in einem ItemsControl dar. Dachte ich…
Nach mehreren Hin & Her hat es nicht so richtig hingehauen, entweder zeigte der mir den Text ohne WordWrapping an, oder, ach was weiß ich, was ich noch für merkwürdige Ergebnisse hatte.
Nach etwas Recherche bin ich dann darauf gekommen, den TextBlock abzuleiten und die erweiterte Klasse um ein DependenyProperty zu erweitern. Und tada, gibts schon : )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public class BindableTextBlock : TextBlock { public static readonly DependencyProperty InlineCollectionProperty = DependencyProperty.Register("InlineCollection", typeof(List<Inline>), typeof(BindableTextBlock), new UIPropertyMetadata(OnInlineCollectionChanged)); private static void OnInlineCollectionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { BindableTextBlock instance = sender as BindableTextBlock; if (instance != null) { List<Inline> newText = e.NewValue as List<Inline>; if (newText != null) { instance.Inlines.Clear(); instance.Inlines.AddRange(newText.ToList()); } } } public List<Inline> InlineCollection { get { return (List<Inline>)GetValue(InlineCollectionProperty); } set { SetValue(InlineCollectionProperty, value); } } } |
Perfekt, genau das was ich brauche.
Im Xaml das Ganze nur noch in die richtige Reihenfolge gebracht:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <Grid> <Grid.Resources> <local:KeywordConverter x:Key="KeywordConverter" /> </Grid.Resources> <DataGrid Name="dataGrid1" AutoGenerateColumns="False" ItemsSource="{Binding Books}"> <DataGrid.Columns> <DataGridTextColumn Header="Name" Binding="{Binding Title}" /> <DataGridTemplateColumn Header="Description" Width="*"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Grid> <local:BindableTextBlock TextWrapping="WrapWithOverflow" InlineCollection="{Binding Description, Converter={StaticResource KeywordConverter}, ConverterParameter='Spur Emma Botschaft Schwur' }"/> </Grid> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> |
sieht das Ganze wie folgt aus:

Die ConverterParameter könnten nun auch an eine Textbox o.ä. gebunden werden.
Wer das Beispiel “von Nahen” sehen möchte, kann dieses auch gerne herunterladen.
Ich würde mich freuen, wenn einer da draußen ist, der vielleicht noch eine andere Idee hat, wenn ja, dann immer her damit!
Na, dann. Viel Spaß beim entwickeln : )







