Reputation: 9862
i have a label
control in windows form
. i want to display full text in the label
. condition is like this:
if possible split by full word, without hyphen(-).
So far i have reach till below code:
private void Form1_Load(object sender, EventArgs e)
{
string strtext = "This is a very long text. this will come in one line.This is a very long text. this will come in one line.";
if (strtext.Length > 32)
{
IEnumerable<string> strEnum = Split(strtext, 32);
label1.Text =string.Join("-\n", strEnum);
}
}
static IEnumerable<string> Split(string str, int chunkSize)
{
return Enumerable.Range(0, str.Length / chunkSize)
.Select(i => str.Substring(i * chunkSize, chunkSize));
}
but issue is that the last line is not displaying entirely because its splitting by 32 character.
Is there another way to achieve this?
Upvotes: 5
Views: 2188
Reputation: 216323
I don't know if you will accept an answer that doesn't use linq, but this is simple:
string SplitOnWholeWord(string toSplit, int maxLineLength)
{
StringBuilder sb = new StringBuilder();
string[] parts = toSplit.Split();
string line = string.Empty;
foreach(string s in parts)
{
if(s.Length > 32)
{
string p = s;
while(p.Length > 32)
{
int addedChars = 32 - line.Length;
line = string.Join(" ", line, p.Substring(0, addedChars));
sb.AppendLine(line);
p = p.Substring(addedChars);
line = string.Empty;
}
line = p;
}
else
{
if(line.Length + s.Length > maxLineLength)
{
sb.AppendLine(line);
line = string.Empty;
}
line = (line.Length > 0 ? string.Join(" ", line, s) : s);
}
}
sb.Append(line.Trim());
return sb.ToString();
}
Call with
string result = SplitOnWholeWord(strtext, 32);
It is possible to transform this in an extension method easily:
Put the code above in a separate file and create a static class
public static class StringExtensions
{
public static string SplitOnWholeWord(this string toSplit, int maxLineLength)
{
// same code as above.....
}
}
and call it in this way:
string result = strtext.SplitOnWholeWord(32);
Upvotes: 2
Reputation: 18474
You could try
static IEnumerable<string> Split(string str, int chunkSize)
{
var count = str.Length / chunkSize;
var result=Enumerable.Range(0, count)
.Select(i => str.Substring(i * chunkSize, chunkSize));
var end = count * chunkSize;
if (end < str.Length) {
result = result.Concat(str.Substring(end, str.Length - end));
}
return result;
}
or
static IEnumerable<string> Split(string str, int chunkSize)
{
for (var i=0; i<str.Length; i+=chunkSize) {
yield return str.Substring(i, Math.Min(str.Length-i, chunkSize));
}
}
EDIT: Justified split, after comment
static IEnumerable<string> split(string str,int chunkSize) {
var words=str.Split(' ');
var line=new StringBuilder(chunkSize);
for (var i=0; i<words.Length;i++) {
var word=words[i];
if (line.Length + word.Length + 1 > chunkSize) {
if (line.Length == 0) {
for(var x=0;x<word.Length/chunkSize;x++) {
yield return word.Substring(x*chunkSize,chunkSize);
}
var remainder = word.Length % chunkSize;
if (remainder>0) {
line.Append(word.Substring(word.Length-remainder, remainder));
}
} else {
yield return line.ToString();
line.Clear();
i--; // Force reprocessing this word
}
} else {
if (line.Length>0) {
line.Append(" ");
}
line.Append(word);
}
}
}
don't forget to change your string.Join("-\n")
to be string.Join("\n")
Upvotes: 0
Reputation: 7438
You have to take the Ceiling of result in the following calculation
str.Length / chunkSize
Right now it will return integer part of the result and ignore if any reminder is there , thus if you have 120 characters in the str , and your chunk size is 50 , the above calculation will give result = 2 which you are using as number of chunks and that is wrong you need 3 here.
To make sure that your division works fine , you can add additional length to the str.length
Use the following code:
static IEnumerable<string> Split(string str, int chunkSize)
{
return Enumerable.Range(0, (str.Length+chunkSize-1) / chunkSize)
.Select(i => str.Substring(i * chunkSize, (str.length-(i*chunkSize))>=chunkSize? chunkSize:str.length-(i*chunkSize)));
}
Upvotes: 0
Reputation: 65077
Throwing my answer into the mix. This works:
static IEnumerable<string> Split(string str, int chunkSize) {
int difference = (str.Length % chunkSize);
int count = str.Length / chunkSize;
return Enumerable.Range(0, count + 1)
.Select(i => str.Substring(i * chunkSize, i == count ? difference : chunkSize));
}
Upvotes: 0
Reputation: 1896
Try this..
string strtext = "This is a very long text. this will come in one line.This is a very long text. this will come in one line.";
if (strtext.Length > 32)
{
IEnumerable<string> strEnum = Split(strtext, 32);
string a = string.Join("-\n", strEnum);
if ((strtext.Length % 32)>0)
{
string lastpart = strtext.Substring(((strtext.Length / 32) * 32));
a = a + "-\n" + lastpart;
}
label1.Text=a;
}
Hope it helps :)
Upvotes: 1