I have a richtextbox in c# and I want to make the links that appear as readonly. Right now I can move my cursor into it and edit it. Is there any way to make it readonly?
You can set this property of a RichTextBox to make the whole text read-only
ReadOnly = true
If you would like to protect the links only but leave other text editable, please try to insert the following whether under Form1_Load or under any method you may create
You'll need to add RichTextBox.Find(string str); from the object browser
MatchCollection mc = Regex.Matches(richTextBox1.Text, #"(www[^ \s]+|http[^ \s]+)([\s]|$)", RegexOptions.IgnoreCase); // Create a new MatchCollection and match from richTextBox1.Text
for (int collection = 0; collection < mc.Count; collection++) // increase collection for every string in mc
{
if (richTextBox1.Find(mc[collection].Value, RichTextBoxFinds.None) > -1) // Find the mc value
{
richTextBox1.SelectionProtected = true; // Protect the value
}
}
So the form would look like this
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
MatchCollection mc = Regex.Matches(richTextBox1.Text, #"(www[^ \s]+|http[^ \s]+)([\s]|$)", RegexOptions.IgnoreCase);
for (int collection = 0; collection < mc.Count; collection++)
{
if (richTextBox1.Find(mc[collection].Value, RichTextBoxFinds.None) > -1)
{
richTextBox1.SelectionProtected = true;
}
}
}
}
}
Thanks,
Have a great day :)
You can change it in your code like this:
richTextBox1.ReadOnly = true;
Or you could go to your design view, check the properties for your richtextbox and set the ReadOnly attribute to true.
You should capture the change event, in such a way that you reset every change a user would like to make to the link and set it back to the original link. Save the positions of the links and update the positions if the user deletes or adds a character.
I would like to share my solution...I did try everything I found on the internet but seems I can't get exactly 100% like I want(to make a richtexbox as readonly). Then I start looking for an alternative which finally I get one to do exactly like I want.
Sometime we need to show the value with a style on it, thats why we choose richtextbox at the 1st time, then it become an issue when we unable to make it as ReadOnly. The different is I am not using the richtextbox anymore but I change it to label. Depending on how your program work, you might need to have 2 control (richtextbox & label) to hold the same value which will be switched(visible true/false) base on your requirement.
See my example here to get a ReadOnly richtextbox look alike control :
<div id="History">
<asp:Label ID="lblLACA27" runat="server" CssClass="ctlLabel"></asp:Label>
</div>
And a piece of CSS code :
#History
{
height: 100px;
float: left;
overflow: auto;
overflow-x: hidden;
}
The DIV tag which hold the LABEL will act like multiline textbox/richtextbox with scrollbar visible on it. Thats it & lets continue programming. Hope this will help someone later.
Related
Hey guys new to C# and I am trying to setup a GUI, all I want the GUI to do is have a simple file explorer with a CheckedListBox to represent selected files.
I can get the CheckedListBox to show up and click on files but I'm not sure how to continue from here, most tutorials stop here, or go too advanced with tree view and other things that seem unnecessary for what I am trying to do.
Here is my code:
Any help is appreciated and if you guys could point me in the right direction that would be awesome.
EDIT:
To rephrase my question:
I want the user to select files through the CheckedListBox (user input stops here), and for those selected files to be put in a list that my code can manipulate.
Not sure how to accomplish this after my first foreach loop (which adds all files in the selected directory to the CheckedListBox for user selection).
The second foreach loop is an attempt at this, manipulating the files so that they output their filenames after being selected. However no Messagebox shows up and I assume that their is a disconnect between the user selecting files and the codes attempt at manipulating said files.
Second Edit:
I think I figured it out I made a second button and from here it looks like I can manipulate the chosen files however I want.
Currently the code is working the way I would expect it to work.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace SelectFiles
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
checkedListBox1.CheckOnClick = true;
}
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
MessageBox.Show(fbd.SelectedPath);
checkedListBox1.Items.Clear();
string[] files = Directory.GetFiles(fbd.SelectedPath);
foreach (string file in files)
{
checkedListBox1.Items.Add(file);
}
}
private void button2_Click_1(object sender, EventArgs e)
{
List<string> list_all_excelfiles = new List<string>();
foreach (string item in checkedListBox1.CheckedItems)
{
list_all_excelfiles.Add(item);
MessageBox.Show(Path.GetFileName(item));
}
}
}
}
First i advice you to assign Value member and Display member for each item.
Display Member will be visible to user
Value Member will we use in code
To do this first create simple custom class
public class Int_String
{
public int _int { get; set; }
public string _string { get; set; }
}
Be careful because get; set; part is important to be there since if not code will not work
Now what you need to do is create list of items with custom class like this
class YourForm : Form
{
List<Int_String> myList = new List<Int_String>(); //Create list of our custom class
public YourForm()
{
PopulateMyList();
}
private void PopulateMyList()
{
//Here read from database or get data somehow and populate our list like this
//I will populate it manually but you do it in foreach loop
myList.Add(new Int_String { _int = 0, _string = "First Item" });
myList.Add(new Int_String { _int = 1, _string = "Second Item" });
myList.Add(new Int_String { _int = 2, _string = "Third Item" });
}
}
After that you need to assign this list to your checkedListBox which you will do like this:
public YourForm()
{
PopulateMyList();
checkedListBox1.DataSource = myList;
checkedListBox1.DisplayMember = "_string";
checkedListBox1.ValueMember = "_int";
}
And now when you can manipulate with checked items like this:
for(int i = 0; i < checkedListBox1.Items.Count; i++)
{
if(checkedListBox1.Items[i].CheckedState == CheckState.Checked)
{
int itemValueMember = (checkedListBox1.Items[i] as Int_String)._int;
int itemDisplayMember = (checkedListBox1.Items[i] as Int_String)._string;
//Use these two vars for whatever you need
}
}
TWO IMPORTANT TIPS:
I am not sure for this one since i am writing all this from head but i think that visual studio will not show you that there is DisplayMember or ValueMember for checkedBox component BUT also it will not show error. Reason is that they have hidden in intentionally for idk what reason but it will work.
You are able to assign Display and Value member to a lot of components in winforms BUT for some reason checkedListBox is specific. It is specific because you MUST first assign DataSource to it and then tell it checkedListBox.DisplayMember = "_string" ...... For new guy you will ask why it is important. Simple answer is create custom list for test and add 10k items inside it and then first declare datasource and after it Display and Value member. Test how long form will need to load (get out of freeze state). After that do everything same but first declare Display and Value member and then assign datasource and test again. I am telling this from head without testing but before when i needed about 5k rows with 1st solution it took me about 30 sec and second < 1 sec. If you want to know more about it google it but for now this is pretty much info for you.
My Question is to how to extend a TextBox such that it may start behaving like RichTextBox?
There can be various properties that RichTextBox may add: appearance mainly.
Should I use this kind of method where I extend the TextBox class and create a basic TextBox which would contain several other textboxes which would behave like a big container node containing small specialized nodes?
For starters, to have texts with alternate color after '+', I ve used this way:
class CustomTextBox : TextBox
{
List<TextBox> _textboxes = new List<TextBox>();
string _Text="";
List<Color> colorlist = new List<Color>();
public override string Text
{
get{return this._Text;}
set{this._Text = value;}
}
public CustomTextBox()
{
foreach(Color color in (Color[]) Enum.GetValues(typeOf(Color)))
{
colorlist.add(color);
}
this.KeyUp+= new KeyUpEventHandler(TextChangedCheck);
}
int i=0;
private void TextChangedCheck(object sender, KeyUpEventArgs e)
{
if(e.KeyData == Keys.Add)
{
TextBox Temp = new TextBox();
Temp.Text = this.Text;
this.Text = "";
Temp.ForeColor = colorlist[i];
i++;
this._textboxes.Add(Temp);
this.Controls.Add(_textboxes[i]);
e.Handled = true;
}
}
}
EDIT:
The MAIN purpose of this question is to extend a TextBox using its own properties to have a RTB like behavior and not using Graphics or related.
I'd have to guess what you really want to achieve here.
But if you want a Control with formatted text (FT) and really really really don't want a RichTextBox, I think you shouldn't create a new, embedded TextBox for every piece of FT.
Instead you should write the FT yourself, maybe on a panel with DrawString and use only one Textbox for text entry. Interesting project, really, once one accepts the challenge. Of course you must think your format through and also consider all sorts of interface questions..
Last week I have avoided a RTF for a tiny help system by using a ListView; it formats by line only, using the first character to indicate the format from a list of a dozen or so.. Works fine, but only one format per line.
So, my XML file is as follows:
<?xml version="1.0" encoding="utf-8" ?>
<quiz>
</answers>
</question>
<!-- More questions here -->
</quiz>
My Form1.cs looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Drawing;
namespace WindowsFormsApplication1
{
public partial class FormMain : Form
{
Basically, all four buttons had the question on them rather than the answers and underneath the bottom left button, there appeared to be a blank button. How do I get the question to display where label1 is and the answers to be on four separate buttons? Also, how will I do it when I start adding multiple questions (User obviously can't move on to the next question unless they get previous one right and difficulty can be chosen at the start to show a different set of questions).
I've been on at this for a while and I think it needs a fresh set of eyes because my relatively novice C# brain can't figure it out. Anyone help me please?
Check out the answer to this question. What is much easier to deal with is Deserialize the XML into a class you've created with a matching structure.
How to Deserialize XML document
More info here:
http://msdn.microsoft.com/en-us/library/58a18dwa.aspx
You are setting the text of every button each time around your loop:
foreach (var question in _questions)
{
button1.Text = question.QuestionText;
button2.Text = question.QuestionText;
button3.Text = question.QuestionText;
button4.Text = question.QuestionText;
}
The last time around the loop, each button will have the text set to the text of the last question.
It also looks a bit odd, as you have four buttons defined as fields of the form, yet you are creating additional buttons in your PopulateForm method but doing nothing with them.
You would be better off getting rid of the fields and working with the newly-created buttons directly:
private void PopulateForm()
{
int count = 0;
foreach (var question in _questions)
{
var button = new Button();
button.Size = new Size(60, 23);
button.Location = new Point(100, 40 + (count * 30));
button.Text = question.QuestionText;
Controls.Add(button);
count++;
}
}
You have to set the location of each button to something different, otherwise they will all show in the same place.
EDIT:
From looking at your code in your zip file, what you want is something like (assuming that your questions have four answers):
private void PopulateForm()
{
foreach (var question in _questions)
{
label1.Text = question.QuestionText;
button1.Text = question.Answers[0];
button2.Text = question.Answers[1];
button3.Text = question.Answers[2];
button4.Text = question.Answers[3];
}
}
hi there I want to change the font style of a label in an aspx page, through choosing options provided by a dorpdownlist. None of these methods work. I know I might be on the right path, but just can't seem to get it right. Please enlighten me. Thanks
In my code behind:
public void button1_Click(object sender, EventArgs e)
{
var select= drop1.SelectedItem.Value;
if(select == "Times New Roman")
{
// I tried doing all of these:
label1.Font= new Font("Times New Roman", label1.Font.Size);
//or
label1.Font.Name ="Times New Roman";
//or
Label new1 = new Label("Times New Roman");
Label1.Font= new1;
}
}
You're better off using jquery
Bind an event handler to the onchange event on the select dropdown and according to the value then change the css class. This has the benefits of a - not being server side and avoiding a hit on the server b - easier c - cleaner
edit : Something like this could be adapted
jQuery onchange/onfocus select box to display an image?
Do you need to make it this way? It's not a 'nice' solution anyway. It's much better to assign an css class. I haven't seen this way before... but I would say that it's comming from WinForms.
Use CssClass instead:
label1.CssClass = "SomeClass";
And define styling in your stylesheet:
.SomeClass { font-family: "Times New Roman"; font-size: 1.2em; }
here is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication2
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Font.Name = "Verdana";
}
}
}
and it is working, i just need you to make sure that before you run the application you set a fontname to your label because the fontname is empty when you put it in your page,(it doesnt work if you dont set a fontname initially) you need to set it then yuse the code i wrte above.open the properties window click the label and click font then choose a name for font name
On web we do not create new Font this works for desktop programming and the new Font are made on server not on client.
The Label contains the .Font but not to set a new font, but to actually create a new inline style, and the object is the FontInfo (not the Font).
From MSDN FontInfo here is an example:
// Note that myLabel.Font is a FontInfo object.
myLabel.Font.Bold = true;
myLabel.Font.Italic = false;
myLabel.Font.Name = "verdana";
myLabel.Font.Overline = false;
myLabel.Font.Size = 10;
myLabel.Font.Strikeout = false;
myLabel.Font.Underline = true;
// Write information on the FontInfo object to the myLabel label.
myLabel.Text = myLabel.Font.ToString();
The final render of this contains inline style to give this properties to the text that is inside a span or a div. Is better of course to give a global css class, but some times you need to interfere with inline style.
Maybe it's something I'm doing wrong. I'm just learning Linq because I'm bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control.
usage: enter text into textbox, click button. program lets you select a file to match the textbox value against and returns matches in label control.
code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace LinqTests
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected internal String[]
Content;
public String
Value;
private void button1_Click(object sender, EventArgs e)
{
Value = textBox1.Text;
OpenFileDialog ofile = new OpenFileDialog();
ofile.Title = "Open File";
ofile.Filter = "All Files (*.*)|*.*";
if (ofile.ShowDialog() == DialogResult.OK)
{
Content =
File.ReadAllLines(ofile.FileName);
IEnumerable<String> Query =
from instance in Content
where instance == Value
orderby instance
select instance;
foreach (String Item in Query)
label1.Text +=
Item + Environment.NewLine;
}
else Application.DoEvents();
ofile.Dispose();
}
}
}
The Problem
What I have above works perfectly, except for one thing. I have a file that I check against which contains the following text:
File:
jason
is
the
funniest
person
in
the
world
jason
jason
jason
pezzimenti
... And it never, ever returns "jason". but it will always return any other word in there.
I'm guessing that it doesn't return a match if there is more that one of the same match?
Would I be correct in saying so? And is this how it's supposed to be? And how would you suggest I make it always return a match no matter how many of the same matches there are. I mean I would have thought that it would return the following output, based on the code above... isn't that what the foreach(Item in Query) is for?, when i type "jason" into the textBox1:
jason
jason
jason
jason
..but it doesn't return any jasons :(
You probably have a blank at the end of the line... try that instead :
IEnumerable<String> Query =
from instance in Content
where instance.Trim() == Value.Trim()
orderby instance
select instance;
You are correct in what you expect to happen, ie, you would get one line displayed per instance of the word in the text file.
It could be that you have blank spaces at the end of your file, as Thomas Levesque has stated, but it could also be that your file does not have the line endings that File.ReadAllLines() is expecting. It expects CRLF endings, so if you have only LF endings for example, you might fine that the method only returns one "line".