I would like to have string containing Inline markups like
var str = "foo bar <Bold>dong</Bold>"
and feed TextBlock with it so the text would get formatted like it would be added to Inlines collection. How could I achive that?
You could wrap the text with a <TextBlock> tag and parse the whole thing as XAML:
public TextBlock CreateTextBlock(string inlines)
{
var xaml = "<TextBlock xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">"
+ inlines + "</TextBlock>";
return XamlReader.Parse(xaml) as TextBlock;
}
Then use the newly created TextBlock as you like. Put it in some Panel
var str = "foo bar <Bold>dong</Bold>";
grid.Children.Add(CreateTextBlock(str));
or perhaps copy its Inlines to another TextBlock.
You can try the below code.
<TextBlock x:Name="txtBlock"/>
string regexStr = #"<S>(?<Str>.*?)</S>|<B>(?<Bold>.*?)</B>";
var str = "<S>foo bar </S><B>dong</B>";
Regex regx = new Regex(regexStr);
Match match = regx.Match(str);
Run inline = null;
while (match.Success)
{
if (!string.IsNullOrEmpty(match.Groups["Str"].Value))
{
inline = new Run(match.Groups["Str"].Value);
txtBlock.Inlines.Add(inline);
}
else if (!string.IsNullOrEmpty(match.Groups["Bold"].Value))
{
inline = new Run(match.Groups["Bold"].Value);
inline.FontWeight = FontWeights.Bold;
txtBlock.Inlines.Add(inline);
}
match = match.NextMatch();
}
Related
I have Xamarin.Forms app which identify URLs from label and provide click to the URL using span gestures and show in a webview.
The sample text which I bind to the label from API result is like this:
test
Test description
Test description2
Files :
https://notification-assets.com/1586370078029
https://notification-assets.com/1586370078037
https://notification-assets.com/1586370078063
How I am fetching URLs from this text:
The urlStr is my text conatins URLS
string[] words = urlStr.Split(' ').ToArray();
formattedString = new FormattedString();
foreach (string str in words)
{
if (IsUrl(str))
{
Span span = new Span() { Text = str + " ", TextColor = Color.FromHex("#261fee"), TextDecorations = TextDecorations.Underline, FontAttributes = FontAttributes.Italic };
span.GestureRecognizers.Add(new TapGestureRecognizer()
{
NumberOfTapsRequired = 1,
Command = new Command(async () => {
await PopupNavigation.Instance.PushAsync(new WebviewPopup(span.Text));
})
});
formattedString.Spans.Add(span);
}
else
{
Span span = new Span() { Text = str + " ", TextColor = Color.Gray };
formattedString.Spans.Add(span);
}
}
private static bool IsUrl(string url)
{
string pattern = #"((https?|ftp|file)\://|www.)[A-Za-z0-9\.\-]+(/[A-Za-z0-9\?\&\=;\+!'\(\)\*\-\._~%]*)*";
Regex reg = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
return reg.IsMatch(url);
}
This will highlight the three URLS, but in My webview I will get the URLS like this
":\nhttps://notification-assets.com/1586370078029\nhttps://notification-assets.com/1586370078037\nhttps://notification-assets.com/1586370078063\n "
First of all I don't want to get the 3 URLs even if we are clicking one of the URLs.
Secondly how to remove the /n and : from the formatted URL? How to solve this? Any help is appreciated.
I would like to dynamically create a series of StackPanels which include several TextBoxes and TextBlocks. I need to be able to get their values, so do I have to make their names globally unique or just unique within the StackPanel?
You cannot access to the TextBoxes which is added to the StackPanel children collection like a normal TextBox. But you can get their values by their name like this:
private static string GetChildValue(Panel panel, string name)
{
var children = panel.Children;
foreach (var child in children)
{
if (!(child is TextBox))
continue;
var textBox = (TextBox)child;
if (textBox.Name.Equals(name))
return textBox.Text;
}
return string.Empty;
}
private static void DoSomething()
{
var stackPanel = new StackPanel();
stackPanel.Children.Add(new TextBox { Name = "TextBox1", Text = "TextBox1 Value" });
stackPanel.Children.Add(new TextBox { Name = "TextBox2", Text = "TextBox2 Value" });
stackPanel.Children.Add(new TextBox { Name = "TextBox3", Text = "TextBox3 Value" });
stackPanel.Children.Add(new TextBox { Name = "TextBox4", Text = "TextBox4 Value" });
var textBox1Value = GetChildValue(stackPanel, "TextBox1");
}
I have long string and show it in ContentDialogResult as
var dlg = new ContentDialog()
{
Title = sTitle,
Content = "This is very long string and i want wrap it but it only appear in 1 line on content of ContentDialogResult. Please help me!",
PrimaryButtonText = sTextBtnMain,
SecondaryButtonText = sTextBtnSub
};
but it only show on 1 line and no wrap. How i can wrap it without custom xaml for ContentDialogResult.
Thanks for all support!
ContentDialog accepts any object as Title and Content property. So, create TextBlock, add TextWrapping property and pass it to Content instead of string object. It will work.
TextBlock txtBlock = new TextBlock();
txtBlock.Text = "This is very long string and i want wrap it but it only appear in 1 line on content of ContentDialogResult. Please help me!";
txtBlock.TextWrapping = TextWrapping.Wrap;
ContentDialog dialog = new ContentDialog()
{
Title = sTitle,
Content = txtBlock,
PrimaryButtonText = sTextBtnMain,
SecondaryButtonText = sTextBtnSub
};
I have an RTB with InlineUIContainer's. I store them in a List, so I can access them directly. How can I remove them from my RTB in C#?
Code example:
// for some TextPointer textPointer in my RTB
TextBlock tb = new TextBlock();
tb.Text = "hello world";
InlineUIContainer inlineUIContainer = new InlineUIContainer(tb, textPointer);
tb_list.Add(inlineUIContainer);
Here, you can remove it like below. If this is your local collection of containers:
List<InlineUIContainer> containers = new List<InlineUIContainer>();
and you want to remove the container which is first in your list then:
InlineUIContainer inlineContainer = containers[0] ;
foreach (var block in myRTB.Document.Blocks)
{
if (block is Paragraph)
{
var paragraph = block as Paragraph;
if (paragraph.Inlines.Contains(inlineContainer))
{
paragraph.Inlines.Remove(inlineContainer);
}
}
}
Im having diffculty with datetime when its displayed client side from my rest web service, my client side wpf app code looks like this:
public MainWindow()
{
InitializeComponent();
string uriGroups = "http://localhost:8000/Service/Student";
XDocument xDoc = XDocument.Load(uriGroups);
foreach(var node in xDoc.Descendants("Student"))
{
GroupBox groupbox = new GroupBox();
groupbox.Header = String.Format(node.Element("StudentID").Value);
groupbox.Width = 100;
groupbox.Height = 100;
groupbox.Margin = new Thickness(2);
TextBlock textBlock = new TextBlock();
textBlock.Text = String.Format(node.Element("FirstName").Value + " " + (node.Element("LastName").Value));
textBlock.TextAlignment = TextAlignment.Center;
TextBlock textBlock1 = new TextBlock();
textBlock1.Text = String.Format(node.Element("TimeAdded").Value);
textBlock1.TextAlignment = TextAlignment.Center;
textBlock1.VerticalAlignment = VerticalAlignment.Bottom;
StackPanel stackPanel = new StackPanel();
stackPanel.Children.Add(groupbox);
stackPanel.Children.Add(textBlock);
stackPanel.Children.Add(textBlock1);
stackPanel.Margin = new Thickness(10);
MainArea.Children.Add(stackPanel);
}
}
And my service looks like this:
public class Student
{
....
public DateTime TimeAdded;
public string TimeAddedString
{
get
{
return this.TimeAdded.ToString("dd/MM/yyyy hh:mm:ss");
}
}
But the output looks like this:
Is there a way on my client side app code to truncate this or reformat it?
You can cast it to a DateTime and then use String.Format
Here is an example with one format you could use:
String.Format("{0:M/d/yyyy}", ((DateTime)node.Element("TimeAdded").Value))
You can also use DateTime.ToString(FORMAT)
((DateTime)node.Element("TimeAdded").Value).ToString("d");
I have made an assumption that .Value returns an object, but if it returns a DateTime then you can drop the casts.
If you are getting a string into your client, then you will need to use DateTime.Parse
(DateTime.Parse(node.Element("TimeAdded").Value)).ToString("d");
String.Format("{0:M/d/yyyy}", DateTime.Parse(node.Element("TimeAdded").Value))
You are using TimeAdded...but I think you should be using TimeAddedString
textBlock1.Text = String.Format(node.Element("TimeAdded").Value);
Should be
textBlock1.Text = String.Format(node.Element("TimeAddedString").Value);
I believe