C# Load TextBlock content from a valriable (containing images) - c#

I just wrote some nice functions, that allow me to add Emojis in a textbox with Inline.Add([Syste.Windows.Controls.Image]). It basically takes a TextBlock as an argument and appends the text/emojis that I want.
Icons is a Dictionary which maps from string to BitmapImage. (unable to use '<' and '>' here somehow)
private void AddTextToString(TextBlock block, string txt)
{
var textRun = new Run(txt);
textRun.BaselineAlignment = BaselineAlignment.Center;
block.Inlines.Add(textRun);
}
private void AddEmojiToString(TextBlock block, string txt)
{
if (!Icons.ContainsKey(txt))
return;
System.Windows.Controls.Image emo = new System.Windows.Controls.Image();
emo.Height = 15;
emo.Width = 15;
emo.VerticalAlignment = VerticalAlignment.Center;
emo.Source = Icons[txt];
block.Inlines.Add(emo);
}
Now I was wondering if there was an elegant way of saving this kind of text to a variable, so that I could bind the TextBlock Text dynamically to it.
Thank you very much in advance!

TextBlock.Inlines is property of type InlineCollection, you can use this type to keep the contents.

Related

Get Text of Node(Item) Treeview in SelectedItemChange Event IN WPF

First of all I am from Iran and I can't speak English very well, sorry for this.
I made something like OpenFileDialog in WinForms and it works correctly.
After that for better User Interface I'm try to make it in WPF.
I use TreeView and other controls to make it work in both platforms (Winforms and WPF).
In WPF I want to get the text of Treeview item for comparison, in Winform I could do this with below code:
private void Folder_FileTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if(e.Node.Text=="Desktop")
{
//Do something
}
}
in WPF I added text with and image next to each other using this method:
public object Node(string NodeIMGUri, string NodeText)
{
Image IMG = new Image() { Source = new System.Windows.Media.Imaging.BitmapImage(new Uri(NodeIMGUri, UriKind.RelativeOrAbsolute)) };
TextBlock Text = new TextBlock() { Text = NodeText };
StackPanel CustomStackPanel = new StackPanel();
TreeViewItem TVItem = new TreeViewItem();
IMG.Height = 50;
IMG.Width = 50;
CustomStackPanel.Orientation = Orientation.Horizontal;
CustomStackPanel.Children.Add(IMG);
CustomStackPanel.Children.Add(Text);
TVItem.Header = CustomStackPanel;
return TVItem;
}
But when in SelectedItemChanged (or ItemChanged) event of TreeView how can I get the text of the item clicked?
If anyone can help me to complete this dll, I can send it free to all programmers.
This dll supports most languages like german, france, china, hindi, bengali, indonesian, persian, japanese, korean, arabic, portuguese, latin, swede, english
The way you are currently doing things, you would need to go through the children of your item to find the TextBlock and get the Text property from that. But this isn't the proper or recommended way of doing things in WPF.
Instead of manually creating TreeViewItems, you shoudl be using TreeView.ItemsSource and TreeView.ItemTemplate. If you're not familiar with how to use DataTemplates in WPF, you should really read up on it. Here is a good place to start.
Basically you would define a class, let's say Folder, then you would have a collection of Folder objects (e.g. List<Folder>), and you would bind that to TreeView.ItemsSource. You would then use a DataTempalte to declare the visual representation of how a Folder object should look in the TreeView. Then, when the selected item is changed, you can use TreeViewItem.DataContext to get the Folder object that is being selected, which would probably have a property such as Path.
So what I can see there you put into your TreeViewItem's header a panel with two items - Image and TextBlock with Text you want to get. The TextBlock is stored as the second item in the panel's collection (Children). All you have to do is this:
private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
CustomStackPanel panel = (CustomStackPanel)((TreeViewItem) e.NewValue).Header;
TextBlock textBlock = (TextBlock)panel.Children[1];
string text = textBlock.Text; //Your text
}
Hope it helps.

It's possible convert string into Label name? [duplicate]

This question already has answers here:
Find control by name from Windows Forms controls
(3 answers)
Closed 4 years ago.
Using C# and Windows Forms, i would like to use the name of a Label as a parameter of another function, like this:
startBox(label_box, "11", Color.Red);
Definition of startBox:
private void startBox(Label label, string text, Color color) {
label.BackColor = color;
label.Visible = true;
label.Enabled = true;
label.Text = text;
}
But, is there any way to convert an string to the name of a Label?
In my case, label_box is a string.
ps¹. I need to do this because i have N Labels and the name is should be typed by the user.
ps². To Invoke a method using a string i used the MethodInfo.
EDIT: The solution using Controls does not apply. In my case, a string is given as an input, if the string is the name of one of the labels the function is called.
Thank you, and sorry for the spelling flaws in English.
so you want to be able to operate on a label, where the name of the label is supplied as input. I would do this with a dictions
var lDict = new Dictionary<string, Label>();
lDict["l1"] = Label1;
lDict["l2"] = Label2;
....
then
void Func(string labelName)
{
var label = lDict[labelName];
label.Visible = true;
...
}
you could do all sorts of complicated reflection tings but that feels like overkill

C# - RichTextBoxPrintCtrl and tabcontrol

Hello (and sorry for my English), I have a problem with Printing RTF using RichTextBoxPrintCtrl and TabControl.
1) The tabcontrol got no tabs on Design, when the Form Load, it will get a tab with the method AddTab(Title). (Don't mind about other variables).
private void AddTab(string Name = "Nuova Nota*")
{
RichTextBox Body = new RichTextBox();
Body.Name = "Body";
Body.Dock = DockStyle.Fill;
Body.ContextMenuStrip = contextMenuStrip1;
TabPage NewPage = new TabPage();
string DocumentText = Nome;
if (Nome == "Nuova Nota*")
{
TabCount += 1;
DocumentText = Nome + TabCount;
}
NewPage.Name = DocumentText;
NewPage.Text = DocumentText;
tabControl1.Visible = true;
NewPage.Controls.Add(Body);
tabControl1.TabPages.Add(NewPage);
tabControl1.SelectedTab = NewPage;
Nomi_Files.Add(NewPage.Text);
Path_Files.Add("");
}
2) Once the tab is created, you can start to write, change colors, fonts, etc...
To get access on the document that you are making, i use a GetCurrentDocument that return the "Body" of the selected tab:
private RichTextBox GetCurrentDocument
{
get { return (RichTextBox)tabControl1.SelectedTab.Controls["Body"];}
}
Now, all the functions (save, open, fonts, colors...) Works Fine, i wanted to print my document and keep the style, so i Googled and i found this: How to print the content of a RichTextBox control by using Visual C#
I made the RichTextBoxPrintCtrl.dll, added the resource on my project, added the item inside the toolbox, but i can't change the RichTextBox that i create from Code, with RichTextBoxPrintCtrl.
The error that i get is:
Error 1 'RichTextBoxPrintCtrl' is a 'namespace' but is used like a
'type'
How i can use that RichTextBoxPrintCtrl without drag and drop it inside the design form?
Ok, i figured out how to solve it:
instead of declaring like:
RichTextBoxPrintCtrl NameControl = new RichTextBoxPrintCtrl();
we need to declare the namespace so:
RichTextBoxPrintCtrl.RichTextBoxPrintCtrl NameControl = new RichTextBoxPrintCtrl.RichTextBoxPrintCtrl();
Everything works fine :) thanks;

How to append Text in xaml Textblock or rich textbox?

I'm creating a chat app in Windows 8 Windows Metro Style App. I need to append the conversation in a richtextblock or textblock in XAML. Would somebody tell me the equivalent for this Code block?
public void AppendConversation(string str)
{
conversation.Append(str);
rtbConversation.Text = conversation.ToString();
rtbConversation.Focus();
rtbConversation.SelectionStart = rtbConversation.Text.Length - 1;
rtbConversation.ScrollToCaret();
rtbSendMessage.Focus();
}
Since WPF uses System.Windows.Controls instead of System.Windows.Forms, we must consider the following
1. System.Windows.Controls.RichTextBox does not have a property for Text to set its value, we may set its value creating a new class of TextRange since the control depends on TextPointer which can be defined using TextRange
string _Text = ""
new TextRange(
rtbConversation.Document.ContentStart,
rtbConversation.Document.ContentEnd).Text = _Text;
2. Selections in System.Windows.Controls.RichTextBox does not depend on int yet they are held by TextPointer. So, we can't say
rtbConversation.SelectionStart = rtbConversation.Text.Length - 1;
but we can say
int TextLength = new TextRange(
rtbConversation.Document.ContentStart,
rtbConversation.Document.ContentEnd).Text.Length;
TextPointer tr = rtbConversation.Document.ContentStart.GetPositionAtOffset(
TextLength - 1, LogicalDirection.Forward);
rtbConversation.Selection.Select(tr, tr);
which will do the same as rtbConversation.SelectionStart = rtbConversation.Text.Length - 1;
Remark: You can always retrieve the beginning of the selection in WPF using RichTextBox.Selection.Start
Notice: RichTextBox.Selection.Start outputs a class of name TextPointer but not a struct of name int
3. Finally, System.Windows.Controls.RichTextBox does not have a definition for ScrollToCaret();. In this case, we may use one of the following voids regarding your control rtbConversation
rtbConversation.ScrollToEnd();
rtbConversation.ScrollToHome();
rtbConversation.ScrollToHorizontalOffset(double offset);
rtbConversation.ScrollToVerticalOffset(double offset);
So, your void should look like this in WPF
Example
public void AppendConversation(string str)
{
conversation.Append(str) // Sorry, I was unable to detect the type of 'conversation'
new TextRange(rtbConversation.Document.ContentStart,
rtbConversation.Document.ContentEnd).Text =
conversation.ToString();
rtbConversation.Focus();
int TextLength = new TextRange(rtbConversation.Document.ContentStart,
rtbConversation.Document.ContentEnd).Text.Length;
TextPointer tr = rtbConversation.Document.ContentStart.GetPositionAtOffset(
TextLength - 1, LogicalDirection.Forward);
rtbConversation.Selection.Select(tr, tr);
rtbConversation.ScrollToEnd();
rtbSendMessage.Focus();
}
Thanks,
I hope you find this helpful :)

How can I calculate the width of a string in Metro (without displaying it)?

I have failed to find a Windows Runtime equivalent to the following WPF code to measure the width of a string:
FormattedText formattedText = new FormattedText(in_string,in_culture,in_flowdir,in_font,in_sz,in_color);
string_width = formattedText.WidthIncludingTrailingWhitespace);
Does anybody know if it can be done in Metro?
It is possible, I've found one method that gives useful measurements, but I am not sure it is the best way of doing it:
// Setup the TextBlock with *everything* that affects how it
// will be drawn (this is not a complete example)
TextBlock^ tb = ref new TextBlock;
tb->VerticalAlignment = Windows::UI::Xaml::VerticalAlignment::Top;
tb->HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Left;
tb->Height = in_height;
tb->Text = text;
// Be sure to tell Measure() the correct dimensions that the TextBox
// have to draw in!
tb->Measure(SizeHelper::FromDimensions(Parent->Width,Parent->Height));
text_width = tb->DesiredSize.Width;
My gut feeling is that there are situations in which this code will give an unexpected result.
Try this:
private double stringWidth(string s, double fontSize)
{
if(s==" ")
s = "\u00A0"; //this line wasn't required in silverlight but is now
TextBlock t = new TextBlock()
{
FontSize = fontSize,
Text = s
};
t.Measure(new Size(double.MaxValue, double.MaxValue)); //this line wasn't required in silverlight but is now
return t.ActualWidth;
}

Categories