| 

.NET C# Java Javascript Exception

1
Hallo,
kann ich irgendwie nur einen bestimmten Teil eines string formatieren. (zb fett).
18.05.2011
mrmee 745 1 8
3 Antworten
8
Mit Substring wäre das möglich. Um dir ein Codebeispiel zu zeigen, wären noch Informationen wichtig, wo du den String den darstellen möchtest (XAML, ASP, RichText).

Update lt. Kommentare:

Hier das versprochene Beispiel:


Umsetzung: So in etwa könnte man das ganze umsetzen.
Im Binding werden dann die ConverterParameter (Keywords) welche fettgeschrieben dargestellt werden sollen definiert.
ConverterParameter='Spur Emma Botschaft Schwur'


Converter:
public class KeywordConverter : IValueConverter
{
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();
}
}

TextBlock-Ableitung (Quelle)

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); }
}
}



XAML:
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication5"
Title="MainWindow" Height="350" Width="525">
<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>
</Window>



Mock Book
public partial class MainWindow : Window
{
public List<Book> Books { get; set; }
public MainWindow()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainWindow_Loaded);
}

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Books = new Book().GetBooks();
dataGrid1.DataContext = this;
}
}

public class Book
{
public string Title { get; set; }
public string Description { get; set; }

public List<Book> GetBooks()
{
List<Book> books = new List<Book>();
books.Add(new Book { Title = "Erlösung", Description = "Der Hilfeschrei im Inneren einer verwitterten Flaschenpost blieb jahrelang unentdeckt. Dann landet die Botschaft im Sonderdezernat Q für unaufgeklärte Fälle. Ihre mühsame Entzifferung führt Carl Mørck und seinen Assistenten Assad auf die Spur eines entsetzlichen Verbrechens: Der Hilfeschrei, mit menschlichem Blut geschrieben, ist offenbar das letzte Lebenszeichen zweier Jungen..." });
books.Add(new Book { Title = "Sonea - Die Heilerin", Description = "Der Schwur der schwarzen Magierin Lorkin, der Sohn der schwarzen Magierin Sonea, wurde in Sachaka entführt. Seine Häscher hoffen, von ihm die Kunst der Heilung durch Magie zu erlernen, die in Sachaka unbekannt ist. Lorkin weiß jedoch, dass diese Fähigkeit im Falle eines Krieges einen enormen Vorteil..." });
books.Add(new Book { Title = "Winterwunder", Description = "Die vier Freundinnen Emma, Mac, Laurel und Parker leiten zusammen eine florierende Hochzeitsagentur. Und bis auf eine haben sie alle die Liebe ihres Lebens gefunden. Nur Parker, das Organisationstalent der Gruppe und eine echte Powerfrau, ist anscheinend..." });
books.Add(new Book { Title = "Das Mitternachtskleid", Description = "Ein neues Märchen von der SCHEIBENWELT voller Spannung, Witz und Magie Tiffany Weh, vielversprechende Junghexe im Teenageralter, hat es nicht leicht. Denn die alltägliche Hexerei erweist sich als ziemlich anstrengend, und ganz bestimmt ist es nicht damit getan, den lieben langen Tag fröhlich auf einem Besen herumzusausen..." });

return books;

}
}


Du kannst das Beispiel auch gerne downloaden.
Ich hoffe ich konnte helfen.

Viel Spaß beim entwickeln ; )
18.05.2011
Mario Priebe 6,0k 3 9
Ich hoffe dass ich deine Frage jetzt richtig beantworte. Der String wird in einer Zelle in einem Datagrid dargestellt. Wenn ein Suchbegriff in diesem string vorhanden ist, sollte der hervorgehoben werden. Hab da eben auch an deinem Tip mit dem Converter gedacht.
mrmee 18.05.2011
Jep, dann ist ein Converter die richtige Wahl. Wie man Text innerhalb eines XAML Elements (TextBlock) formatiert, kannst du hier nachlesen: http://www.biggle.de/blog/text-innerhalb-eines-textblock-controls-formatieren-xaml-wpf-silverlight Solltest du nicht weiterkommen, einfach nochmal nachfragen ;)
Mario Priebe 18.05.2011
Kann sein das ich auf der Leitung stehe, aber wie mach ich das, wenn ich die Spalten erst zur Laufzeit bekomme. Arbeite mit WPF noch nicht sehr lange und blick da noch nicht ganz durch.
mrmee 18.05.2011
Ich erweitere meine Antwort zu heute Abend um ein Codebeispiel, atm bin ich etwas "kurz angebunden" ;)
Mario Priebe 18.05.2011
Super danke. :)
mrmee 18.05.2011
und wie versprochen, hier ein Beispiel wie man das ganze umsetzen könnte.
Mario Priebe 18.05.2011
..hab meine Antwort um dieses erweitert ;)
Mario Priebe 18.05.2011
Wow, bin morgen leider nicht im Büro, werde das Bsp aber am Freitag gleich testen. :)
mrmee 18.05.2011
0
Danke für dein ausführliches Bsp. Das war schon sehr hilfreich. Ich hab aber jetzt leider noch 2 Fragen.
1. Wie kann ich das ganze einem Datagrid beibringen, das erst zur Laufzeit automatisch erzeugt wird. d.h. Daten werden aus einem Dataset bereitgestellt. Spalten werden automatisch erzeugt.

2. Kann der ConverterParameter auch Text einer Textbox enthalten. Hab im Netz was gefunden, dass es nicht möglich ist ein Binding dran zu hängen.
20.05.2011
mrmee 745 1 8
1
zu 1.: du muss dich an das Event dataGrid1.AutoGeneratingColumn hängen und in dieser Methode dein Template zuweisen. Siehe hier: http://social.msdn.microsoft.com/Forums/de/visualcsharpde/thread/3f1dbce6-6baf-4e3b-86bc-0e33b0cd42ec

zu 2.: Hier muss man sich ein DependenyProperty erstellen (was ich auch nicht wusste) schau dazu mal hier: http://marlongrech.wordpress.com/2008/08/03/my-wish-came-true-i-can-now-use-databinding-in-a-converterparameter/
Mario Priebe 20.05.2011
0
So, hab mir jetzt den Link zu 1. angesehen und soweit auch verstanden (glaub ich ;-) ) Allerdings funktioniert das noch nicht so richtig.
Und zwar hab ich jetzt folgendes Datatemplate erstellt.

<UserControl.Resources>
<DataTemplate x:Key="myDataTemplate">
<local:BindableTextBlock TextWrapping="WrapWithOverflow" InlineCollection="{Binding Text, Converter={StaticResource KeywordConverter}, ConverterParameter='ein and te'}" />
</DataTemplate>
</UserControl.Resources>


Und im datagrid1_AutogeneratingColumn folgendes probiert.
private void dataGrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.Column.Header.ToString() == "Text")
{
//e.Cancel = true;
DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
templateColumn.Header = "Neuer Header";
templateColumn.CellTemplate = (DataTemplate)Resources["myDataTemplate"];
e.Column = templateColumn;
}
}

Die Spalte bleibt aber leer. Was mach ich falsch?
23.05.2011
mrmee 745 1 8
Der neue Header wird allerdings angezeigt.
mrmee 23.05.2011
1
So habs jetzt hinbekommen. Ich hatte das Datatemplate an der falschen Stelle. Muss unter App.xaml Application.Ressources definiert werden, damit es gefunden wird. (Wusste ich nicht)
mrmee 25.05.2011

Stelle deine .net-Frage jetzt!