Concatenation of a Complicated String Causing Issues - winforms

I have assigned a piece of code to a string in a proper format. Checked that it works fine. Now I wish to get a copy of this code concatenated to the old code on a button click.Also there are variables within the string which take up values from textboxes. But somehow these variables(arrays) are not able to store the last values. I want to generate the code while placing all the variables at proper places.
public string oldCode;
public int counter=0;
string[] AffUrl = new string[100];
string[] ImgUrl = new string[100];
private void button1_Click(object sender, EventArgs e)
{
AffUrl[counter] =textBox1.Text;
ImgUrl[counter] = textBox2.Text;
string code = #"<div style=""float:left;padding-right:30px;padding-bottom:30px;"">
<div>
<img src=""" + ImgUrl[counter] + #""" height=""200px"" width=""200px"" />
</div>
<div>
<button onclick=""myFunction()"">Try it</button>
<script type=""text/javascript"">
function myFunction" + counter + #"() {
var btn = document.createElement(""BUTTON"");
window.open(""" + AffUrl[counter] + #""", ""_self"")
}
</script>
</div>
</div>";
oldCode = code;
oldCode = string.Concat(code,oldCode);
counter++;
richTextBox1.Text =oldCode;
}

As written, you're always concatenating the new value to itself. Remove the oldCode = code assignment.

</div>";
oldCode = code; <= here you reset the cache - are you sure that's intended?
oldCode = string.Concat(code,oldCode);

Ok, I got it!
You can place a condition over "oldCode=code;
public string oldCode;
public int counter = 0;
string[] AffUrl = new string[100];
string[] ImgUrl = new string[100];
private void button1_Click(object sender, EventArgs e)
{
AffUrl[counter] = textBox1.Text;
ImgUrl[counter] = textBox2.Text;
string code = #"<div style=""float:left;padding-right:30px;padding-bottom:30px;"">
<div>
<img src=""" + ImgUrl[counter] + #""" height=""200px"" width=""200px"" />
</div>
<div>
<button onclick=""myFunction()"">Try it</button>
<script type=""text/javascript"">
function myFunction" + counter + #"() {
var btn = document.createElement(""BUTTON"");
window.open(""" + AffUrl[counter] + #""", ""_self"")
}
</script>
</div>
</div>";
if (counter == 0)
{
oldCode = code;
}
oldCode = string.Concat(code, oldCode);
counter++;
richTextBox1.Text = oldCode;
}
}
}

Related

How to change color of a DrawingVisual on MouseHit

The following code is an adaptation of the code example on page 502 of Adam Nathan, WPF 4.5 unleashed.
Following the advice there I created a class VisualHostClass that "hosts" a list of DrawingVisuals, thereby making them displayable. This worked so far.
Now I wanted to react to a left mouse click by changing the color of the displayed visual. The code for this is in the method HitTestCallback.
With the included Trace.WriteLine statements I can see that the relevant line
drw.Brush = Brushes.Red;
is reached and the property Brush has a new value afterwards. But: The display does not change, the clicked-on DrawingVisual is still Yellow afterwards (that was the brush color used on creation).
What can/should I do here? (I am absolute beginner with WPF).
Thanks in advance for all answers!
public partial class VisualHostClass : FrameworkElement
{
public VisualHostClass()
{
}
public List<DrawingVisual> myVisuals = new List<DrawingVisual>();
public void AddVisual(DrawingVisual dvs)
{
myVisuals.Add(dvs);
AddVisualChild(dvs);
AddLogicalChild(dvs);
}
protected override int VisualChildrenCount
{
get { return myVisuals.Count; }
}
protected override Visual GetVisualChild(int index)
{
if (index < 0 || index >= myVisuals.Count)
{
throw new ArgumentOutOfRangeException("index");
}
return myVisuals[index];
}
public void removeAllChilds()
{
foreach (DrawingVisual dvs in myVisuals)
{
RemoveVisualChild(dvs);
RemoveLogicalChild(dvs);
}
myVisuals.Clear();
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
Point location = e.GetPosition(this);
VisualTreeHelper.HitTest(this, null,
new HitTestResultCallback(HitTestCallback),
new PointHitTestParameters(location));
}
public HitTestResultBehavior HitTestCallback(HitTestResult result)
{
if (result.VisualHit.GetType() == typeof(DrawingVisual))
{
DrawingVisual dv = result.VisualHit as DrawingVisual;
Trace.WriteLine("HitTestCallback: dv = " + dv.ToString());
foreach(GeometryDrawing drw in dv.Drawing.Children)
{
Trace.WriteLine("HitTestCallback: drw = " + drw.ToString());
Trace.WriteLine("HitTestCallback: drw.Geometry = " + drw.Geometry.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
drw.Brush = Brushes.Red;
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
}
}
return HitTestResultBehavior.Continue;
}
}
}
EDIT: After some experimenting the following worked (but it is not satifying for me, as I can only change the Color of a SolidColorBrush, but not the Brush itself):
public void ChangeBrush(DrawingVisual dv)
{
Trace.WriteLine("HitTestCallback: dv = " + dv.ToString());
foreach (Drawing drw1 in dv.Drawing.Children)
{
if (drw1 is GeometryDrawing)
{
GeometryDrawing drw = drw1 as GeometryDrawing;
Trace.WriteLine("HitTestCallback: drw = " + drw.ToString());
Trace.WriteLine("HitTestCallback: drw.Geometry = " + drw.Geometry.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush.IsFrozen = " + drw.Brush.IsFrozen.ToString());
// does not work
//SolidColorBrush newBrush = new SolidColorBrush(Colors.Red);
//newBrush.Freeze();
//drw.Brush = newBrush;
// works with drw.Brush already containing a SolidColorBrush
(drw.Brush as SolidColorBrush).Color =
(drw.Brush as SolidColorBrush).Color == Colors.LightGoldenrodYellow ?
Colors.Red : Colors.LightGoldenrodYellow;
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush.IsFrozen = " + drw.Brush.IsFrozen.ToString());
}
}
}
Just for the record I cite the code where the DrawingVisual is constructed and put in VisualHostClass
PathGeometry pgnGeom = RenderPolygonWithHoles2Geometry(pgn);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
SolidColorBrush brush1 = new SolidColorBrush(Colors.LightGoldenrodYellow);
dc.DrawGeometry(brush1, null, pgnGeom);
}
myVisualHost.AddVisual(dv);
It appears that the Drawing created by dc.DrawGeometry(...) is frozen, i.e. not modifiable.
Passing my own Drawing has worked for me:
using (var dc = dv.RenderOpen())
{
dc.DrawDrawing(new GeometryDrawing(Brushes.LightGoldenrodYellow, null, pgnGeom));
}

How do I call a control that was created dynamically in c#

First, a great thank you to those who asked/responded to questions. You were able to get me this far.
I wanted to help a young Belgian entrepreneur by taking on a challenge, build a Media managing software to display various media types (Images, Videos, links, text) on huge LED screens.
I have limited coding experience as I work in EDI.
My issue is that I create playlists dynamically based on the number of playlists in the DB (see screenshot), but I cannot trigger the playing of the right playlist when pressing the play button.
Warning, my code is noob code.
PlayList ScreenShot
Label playListLbl = new Label();
GroupBox playListGrp = new GroupBox();
public GroupBox addplayListGrp(int i, int start, int end)
{
GroupBox playListGrp = new GroupBox();
playListGrp.Name = "playListGrp"+ Convert.ToString(1 + i);
playListGrp.Text = "Play list " + Convert.ToString(1 + i);
playListGrp.Font = new Font("Century Gothic", 12F,
FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
playListGrp.Width = 425;
playListGrp.Height = 525;
playListGrp.Margin = new Padding(1);
playListGrp.Location = new Point(start, end);
return playListGrp;
}
Button addPlayBtn(int i)
{
Button PlayBtn = new Button();
PlayBtn.Font = new Font("Century Gothic", 9.75F,
System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
PlayBtn.ForeColor = Color.Black;
PlayBtn.Location = new Point(10, 467);
PlayBtn.Name = "playBtn" + Convert.ToString(1 + i);
PlayBtn.Size = new Size(100, 30);
PlayBtn.TabIndex = 6;
PlayBtn.Text = "Play";
PlayBtn.UseVisualStyleBackColor = true;
PlayBtn.Click += new EventHandler(playBtn1_Click);
return PlayBtn;
}
public BMS_main()
{
int startPos = 5;
int endPos = 5;
for (int i = 1; i <= playlistCountInc; i++)
{
playListGrp = addplayListGrp(i, startPos, endPos);
playListLbl = addLabel(i);
Label playListLblTime = addLabelTime(i);
Button PlayBtn = addPlayBtn(i);
}
playListGrp.Controls.Add(playListLbl);
playListGrp.Controls.Add(playListLblTime);
playListGrp.Controls.Add(playlistView);
playListGrp.Controls.Add(PlayBtn);
}
private void playBtn1_Click(object sender, EventArgs e)
{
if (ScreenStatus)
{
Playing = true;
DisplayTimer.Stop();
DisplayTimer.Enabled = false;
InitialScreenTimer.Stop();
InitialScreenTimer.Enabled = false;
PlayListTimer.Enabled = true;
PlayListTimer.Start();
}
else
{
message = "Veuillez alimenter les panneaux";
result = MessageBox.Show(message, caption, buttons);
}
public void PlayListTimer_Tick(object sender, EventArgs e)
{
Label lblAcessorio4 =
(Label)playListLbl.Controls.Find("playLbl4",
true).FirstOrDefault();
if (lblAcessorio4 != null)
{
lblAcessorio4.Text = "Test lblAcessorio4";
}
else
{
message = "Label is null";
result = MessageBox.Show(message, caption, buttons);
}
Set the Tag property of your button with something which will help you decide later on which song to play:
playListGrp = addplayListGrp(i, startPos, endPos);
playListLbl = addLabel(i);
Label playListLblTime = addLabelTime(i);
Button PlayBtn = addPlayBtn(i);
// You can do this
PlayBtn.Tag = playListGrp; // or anything else
Then in the button click handler, get the value of the Tag and make a decision based on that. Just keep in mind that whatever you set the Tag to, you will need to cast it back to that type. For example, in the above I set it GroupBox so I will cast it to a GroupBox:
private void playBtn1_Click(object sender, EventArgs e)
{
GroupBox gb = ((Button)(sender)).Tag as GroupBox;
// Now make the decision
if(gb.Name == "whatever you need to put here"){ // do whatever }
}
I would put the lisbox and then get the selected item and play that.

Click event for button in winform is firing repeatedly for number of values in List

I have a windows form (parent) that takes a value from textbox and then opens child form which then uses that value to select an image from a directory. When multiple images are found for the particular value, I have the form modified to display a couple of buttons to navigate (Next & Previous) to display the different images. Upon first opening the parent form, entering a value and then using form.show() to display the child form – everything works as expected. But if another value is entered into parent form (child form can still be open or exited (hidden)) and the ‘Next’ button is clicked the code in the click event is running over again for however many number of images are in the List(imagesFound). Say I have 3 images in the List(imagesFound) and I step through the code in debug mode the btnNext click event fires 3 times in a row. This of course runs GetMultiImages method which causes sequence of displaying the images to be all of. And again, this doesn’t happen the first time a value is entered into parent form. I’ve made sure the list and other variables are cleared out in GetImage method. I’m stumped…any ideas?
Form1:
public partial class Form1 : Form
{
private string parcelID;
Form2 viewer = new Form2();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
parcelID = txtParID.Text;
ShowViewer();
}
private void ShowViewer()
{
viewer.GetImage(parcelID);
if (viewer.NoImageFound == true)
{
viewer.Show();
viewer.Focus();
}
else if (viewer.NoImageFound == false)
{
viewer.Hide();
}
}
}
Child Form:
public partial class Form2 : Form
{
public Button btnNext = new Button();
public Button btnPrev = new Button();
private List<string> imagesFound = new List<string>();
private string Path;
private string parcel;
private int increment;
private int maxNum;
public bool NoImageFound;
//multi image members
private string firstMultiItem;
private string selectMultiImage;
Image parMultiImage;
public Form2()
{
InitializeComponent();
}
public void GetImage(string ParcelID)
{
NoImageFound = true;
parcel = ParcelID;
increment = 0;
maxNum = 0;
firstMultiItem = null;
selectMultiImage = null;
parMultiImage = null;
imagesFound.Clear();
Path = "........\\Images\\";
try
{
if (!string.IsNullOrEmpty(parcel))
{
string parcelTrim = parcel.Substring(0, 6);
Path = Path + parcelTrim + "\\";
foreach (string s in Directory.GetFiles(Path, parcel + "_" + "*"))
{
string trimString = s.Replace(Path, "");
imagesFound.Add(trimString);
}
if ((imagesFound.Count == 0))
{
MessageBox.Show("No images found for ParcelID: " + parcel);
picBox.Image = null;
this.Text = "";
NoImageFound = false;
}
else
{
if (imagesFound.Count == 1)
{
string firstItem = imagesFound[0].ToString();
string selectImage = Path + firstItem;
Image parImage = Image.FromFile(selectImage);
//in order to access the picture box control you have to change it's
//access modifier (Modifier) from private to public. Defaults to private
picBox.Image = parImage;
picBox.SizeMode = PictureBoxSizeMode.StretchImage;
this.Text = parcel;
SingleForm();
}
else if (imagesFound.Count > 1)
{
firstMultiItem = imagesFound[0].ToString();
maxNum = imagesFound.Count;
selectMultiImage = Path + firstMultiItem;
parMultiImage = Image.FromFile(selectMultiImage);
picBox.Image = parMultiImage;
picBox.SizeMode = PictureBoxSizeMode.StretchImage;
this.Text = parcel;
MultiImageForm();
}
}
}
else
{
MessageBox.Show("No ParcelID");
}
}
catch (DirectoryNotFoundException)
{
string text = parcel;
MessageBox.Show("ParcelID: " + text + " could not be found. The directory may be missing.", "There's a problem locating the image.",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void SingleForm()
{
this.Height = 400;
btnNext.Visible = false;
btnPrev.Visible = false;
}
private void MultiImageForm()
{
//set form properties
this.Text = parcel;
this.Height = 432;
//set btnNext properties
btnNext.Location = new Point(307, 375);
btnNext.Size = new Size(75, 25);
btnNext.Font = new Font("Maiandra GD", 10, FontStyle.Bold);
btnNext.Text = ">>";
//add btnNext to form
this.Controls.Add(btnNext);
btnNext.Visible = true;
btnNext.Enabled = true;
//creating event handler for btnNext
btnNext.Click += new EventHandler(btnNext_Click);
//set btnPrev properties
btnPrev.Location = new Point(12, 375);
btnPrev.Size = new Size(75, 25);
btnPrev.Font = new Font("Maiandra GD", 10, FontStyle.Bold);
btnPrev.Text = "<<";
//add btnPrev to form
this.Controls.Add(btnPrev);
btnPrev.Visible = true;
btnPrev.Enabled = false;
//creating event handler for btnPrev
btnPrev.Click += new EventHandler(btnPrev_Click);
}
private void GetMultiImages()
{
try
{
firstMultiItem = imagesFound[increment].ToString();
selectMultiImage = Path + firstMultiItem;
parMultiImage = Image.FromFile(selectMultiImage);
picBox.Image = parMultiImage;
picBox.SizeMode = PictureBoxSizeMode.StretchImage;
}
catch (IndexOutOfRangeException)
{
MessageBox.Show("Index was out of range.");
}
}
private void btnNext_Click(object sender, System.EventArgs e)
{
if (increment != maxNum - 1)
{
increment++;
GetMultiImages();
}
EnableButtons();
}
private void btnPrev_Click(object sender, System.EventArgs e)
{
if (increment > 0)
{
increment--;
GetMultiImages();
}
EnableButtons();
}
private void EnableButtons()
{
if (increment == 0)
{
btnPrev.Enabled = false;
btnNext.Enabled = true;
}
else if (increment > 0 & increment != maxNum - 1)
{
btnPrev.Enabled = true;
btnNext.Enabled = true;
}
else if (increment == maxNum - 1)
{
btnPrev.Enabled = true;
btnNext.Enabled = false;
}
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
//overriding closing event
this.Hide();
e.Cancel = true;
}
}
//creating event handler for btnNext
btnNext.Click += new EventHandler(btnNext_Click);
That's a bug. You keep adding a Click event handler for the button, each time you call MultiImageForm(). So the event handler runs multiple times for a single click.
Only add event handlers in the form constructor so you can be sure it is only done once.

unable to set Row.Readonly=false in Datagridview in winforms

I have a datagridview with its ReadOnly set true to prevent people editing.
then I have a button on each row. when I click on a specific button, I wrote:
private void DGGrade_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex > 0 && e.ColumnIndex == DGGrade.Columns["Edit"].Index)
{
DGGrade.Rows[DGGrade.CurrentCell.RowIndex].ReadOnly = false;
DGGrade.Rows[DGGrade.CurrentCell.RowIndex].DefaultCellStyle.BackColor = Color.White;
}
But it is not working. please help
I do not know the reason why it is not working but as far as i can tell from my test runs it has to deal how the data is bound. If you use dataGridView1.DataSource = GetDataSource(); then it did not work in my tests. I have read once about some of the drawbacks of automated binding but i could not find it. Here is the code that works. A row is only in EditMode after the User has clicked the button Edit in the corresponding row. I will be back later - let me know if you need more pointers.
public partial class Form1 : Form
{
int rowIndexOfEditableRow = -1;
public Form1() {
InitializeComponent();
CreateDataGridView(dataGridView1);
SetExistingDataGridViewRowsReadOnly();
this.dataGridView1.Columns.Add(GetBtnColumn());
}
private void SetExistingDataGridViewRowsReadOnly() {
DataGridViewRowCollection rows = this.dataGridView1.Rows;
foreach (DataGridViewRow row in rows) {
row.ReadOnly = true;
}
}
It seems that the grid must be filled manually - at least this way the change of ReadOnly works
public void CreateDataGridView(DataGridView dgv)
{
dgv.ColumnCount = 3;
dgv.Columns[0].Name = "Id";
dgv.Columns[1].Name = "Lastname";
dgv.Columns[2].Name = "City";
dgv.BackgroundColor = Color.Gray;
AddRowsToDataGridView(dgv);
}
private void AddRowsToDataGridView(DataGridView dgv)
{
string[] row1 = new string[]{"1", "Muller", "Seattle"};
string[] row2 = new string[]{"2", "Arkan", "Austin"};
string[] row3 = new string[]{"3", "Cooper", "New York"};
object[] rows = new object[] { row1, row2, row3 };
foreach (string[] rowArray in rows)
{
dgv.Rows.Add(rowArray);
}
}
Helper method to create a column with a button
public DataGridViewButtonColumn GetBtnColumn()
{
DataGridViewButtonColumn btnColumn = new DataGridViewButtonColumn();
btnColumn.HeaderText = "Edit";
btnColumn.Text = "Edit";
btnColumn.UseColumnTextForButtonValue = true;
return btnColumn;
}
Event handler checks if the user has clicked the edit button. In this case the current row will be set to ReadOnly = false. This allows that the user to edit the row. To emphasize it i changed the background color of the row.
private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
int colIndex = e.ColumnIndex;
int rowIndex = e.RowIndex;
Type cellType = dataGridView1.Columns[colIndex].CellType;
if (cellType == typeof(DataGridViewButtonCell))
{
dataGridView1.Rows[rowIndex].ReadOnly = false;
dataGridView1.Rows[rowIndex].DefaultCellStyle.BackColor = Color.GreenYellow;
this.rowIndexOfEditableRow = rowIndex;
label1.Text = rowIndexOfEditableRow.ToString() + " " + colIndex.ToString();
}
}
If the Row-leave-Event is fired the style is reset and the global parameter which row is editable is set to the initial value
private void DataGridView1_RowLeave(object sender, DataGridViewCellEventArgs e)
{
int rowIndex = e.RowIndex;
dataGridView1.Rows[rowIndex].ReadOnly = true;
dataGridView1.Rows[rowIndex].DefaultCellStyle.BackColor = Color.White;
this.rowIndexOfEditableRow = -1;
}
}
The above code contains all (except the designer files) that you need to create this demo:

Need to replace an img src attrib with new value

I'm retrieving HTML of many webpages (saved earlier) from SQL Server. My purpose is to modify an img's src attribute. There is only one img tag in the HTML and it's source is like so:
...
<td colspan="3" align="center">
<img src="/crossword/13cnum1.gif" height="360" width="360" border="1"><br></td>
...
I need to change the /crossword/13cnum1.gif to http://www.nostrotech.com/crossword/13cnum1.gif
Code:
private void ReplaceTest() {
String currentCode = string.Empty;
Cursor saveCursor = Cursor.Current;
try {
Cursor.Current = Cursors.WaitCursor;
foreach (WebData oneWebData in DataContext.DbContext.WebDatas.OrderBy(order => order.PuzzleDate)) {
if (oneWebData.Status == "Done" ) {
currentCode = oneWebData.Code;
#region Setup Agility
HtmlAgilityPack.HtmlDocument AgilityHtmlDocument = new HtmlAgilityPack.HtmlDocument {
OptionFixNestedTags = true
};
AgilityHtmlDocument.LoadHtml(oneWebData.PageData);
#endregion
#region Image and URL
var imageOnPage = from imgTags in AgilityHtmlDocument.DocumentNode.Descendants()
where imgTags.Name == "img" &&
imgTags.Attributes["height"] != null &&
imgTags.Attributes["width"] != null
select new {
Url = imgTags.Attributes["src"].Value,
tag = imgTags.Attributes["src"],
Text = imgTags.InnerText
};
if (imageOnPage == null) {
continue;
}
imageOnPage.FirstOrDefault().tag.Value = "http://www.nostrotech.com" + imageOnPage.FirstOrDefault().Url;
#endregion
}
}
}
catch (Exception ex) {
XtraMessageBox.Show(String.Format("Exception: " + currentCode + "!{0}Message: {1}{0}{0}Details:{0}{2}", Environment.NewLine, ex.Message, ex.StackTrace), Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally {
Cursor.Current = saveCursor;
}
}
I need help as the markup is NOT updated this way and I need to store the modified markup back to the DB. Thanks.
XPATH is much more consise than all this XLinq jargon, IMHO...
Here is how to do it:
HtmlDocument doc = new HtmlDocument();
doc.Load(myHtml);
foreach (HtmlNode img in doc.DocumentNode.SelectNodes("//img[#src and #height and #width]"))
{
img.SetAttributeValue("src", "http://www.nostrotech.com" + img.GetAttributeValue("src", null));
}
This code searches for img tags that have src, height and width attributes. Then, it replaces the src attribute value.

Resources