I made a program that can add formatted (change font,size and colour) data using a richtextbox into my MS Access Database, there is also a normal text box to store the topics which is loaded to a listbox when you click on a topic in the listbox it is supposed to display the formatted text in another richtextbox, it displays the plain text perfectly but as soon as a topic is clicked with formatted text it displays how the text was formatted:
{\rtf\ansi\ansicpg 1252\deflang7177{\f0\fnil\fcharset 0 Microsoft Sans serif;}}
{\colortbl;\red0\green255\blue128;}
\viewkind4\uc 1\pard\cf1\fs17 now\cf0\par
}
My code:
private void listItem_SelectedIndexChanged(object sender, EventArgs e)
{
string connstring = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Temp\SumWizz.accdb";
OleDbConnection conn = new OleDbConnection(connstring);
string query = "SELECT * FROM Items WHERE Name = '" + listItem.Text + "'";
OleDbCommand cmd = new OleDbCommand(query, conn);
OleDbDataReader reader;
try
{
conn.Open();
reader = cmd.ExecuteReader();
// reads the data and fills the combo box and listbox
while (reader.Read())
{
string Sdetail = reader.GetString(2);
richItem.Text = Sdetail;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
conn.Close();
}
I have changed richItem (my richtextbox) to richItem.rtf = Sdetail;
Then it displays the formatted text perfectly but when topic selected with plain text it says format invalid, I have to use it in 2 more places. is there a check I can do to first check if the text has rtf properties or any other way to get it to display both plain and formatted text?
Rich text seems to always starts with {\rtf (I may be wrong. But it seems like a fair assumption). So it you check for that, you'll be able to decide.
Please see this link for a convenient extension method to do this.
Code from msdn forum
/// <summary>
/// Returns the DataFormat string of the text.
/// </summary>
/// <param name="text">Text to check.</param>
/// <returns>Value from the <see cref="DataFormats"/> enumeration.</returns>
public static string GetDataFormat(this string text)
{
// First validate the text
if (string.IsNullOrEmpty(text)) return System.Windows.DataFormats.Text;
// Return right data
if (text.StartsWith(#"{\rtf")) return System.Windows.DataFormats.Rtf;
// Return default
return System.Windows.DataFormats.Text;
}
Usage:
var format = myString.GetDataFormat();
if (format == System.Windows.DataFormats.Rtf)
{
// process RTF text
}
else
{
// process plain text
}
Related
First of all, if I click a button the method cbBefüllen will execute.
private void btnEntfernen_Click(object sender, EventArgs e)
{
FeiertageEntfernen entfernen = new FeiertageEntfernen();
entfernen.cbBefüllen();
entfernen.Show();
entfernen.Focus();
}
The following method is just here as an interface between my form and a class. (Please don't ask, in my code I have some good reasons for it ;) ).
public void cbBefüllen()
{
database.cbFeiertagebefüllen();
}
The method cbFeiertagebefüllen (tries to) fills my ComboBox, which is located in the form "feiertagentfernen".
public void cbFeiertagebefüllen()
{
FeiertageEntfernen feiertagentfernen = new FeiertageEntfernen();
string Query = #"select bezeichnung from feiertage";
using (var command = new SQLiteCommand(Query, sqlite_conn))
{
if (sqlite_conn.State != ConnectionState.Open)
{
sqlite_conn.Open();
}
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
string übergabe = reader.GetString(0);
feiertagentfernen.cbFeiertag.Items.Add(übergabe);
}
}
}
}
But after this whole process my ComboBox is still empty. The reader in the last picture picks the correct value from the database, but somehow it won't write it into the ComboBox.
Your problem is in this line:
FeiertageEntfernen feiertagentfernen = new FeiertageEntfernen();
in your cbFeiertagebefüllen()
You make a new form but you want your combo box from the form from the 1st piece of code to be filled. To fix this you could pass along an instance of the form to the filling method.
The updated 2 pieces of code will be (first piece can be left alone):
In cbBefullen:
database.cbFeiertagebefüllen(this);
//'this' means we're passing along the form as parameter
In cbFeiertagebefüllen:
public void cbFeiertagebefüllen(FeiertageEntfernen feiertagentfernen)
{
string Query = #"select bezeichnung from feiertage";
using (var command = new SQLiteCommand(Query, sqlite_conn))
{
if (sqlite_conn.State != ConnectionState.Open)
{
sqlite_conn.Open();
}
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
string übergabe = reader.GetString(0);
feiertagentfernen.cbFeiertag.Items.Add(übergabe);
}
}
}
}
The FeiertageEntfernen form instance on which you're filling the cbFeiertag combo box in cbFeiertagebefüllen() is not the form's instance you're showing after that. You need to pass the entfernen instance to cbFeiertagebefüllen():
public void cbBefüllen()
{
database.cbFeiertagebefüllen(this);
}
public void cbFeiertagebefüllen(FeiertageEntfernen feiertagentfernen)
{
// Use the passed in instance instead of a newly created one
//FeiertageEntfernen feiertagentfernen = new FeiertageEntfernen();
string Query = #"select bezeichnung from feiertage";
// ....................
}
For this to work, the ComboBox which you need to fill, should be globally declared, i.e. outside the scope of your functions. The rest is probably fine. Also it's better if you get the values you need to display in the comboBox to the main form rather than calling the ComboBox instance 2 levels deeper.
I know this is a little confusing, in simple words, What you could do is, fill the values(descriptions of the holidays) from the DataBase into a list. Make your functions return this list when called. And finally where the ComboBox is declared, you could just add that list as the source of the ComboBox
It looks like you are adding the options to the combo box, but you are not actually setting the selected item.
To do so, you need to set cbFeiertag.SelectedIndex or cbFeiertag.SelectedValue.
I have a bit of a weird problem here. I'm attempting to create a form that, when making a selection from a ListBox, will poll data from a database and display it in a RichTextBox. I need the data to be in RTF for formatting purposes.
It works fine if I do something like this:
private void SaveListTest_SelectedIndexChanged(object sender, EventArgs e)
{
DescriptionName = Convert.ToString(SaveListTest.SelectedItem);
//CallDescriptionTest();
CallDescriptionTest2();
SaveRichTest.Rtf = DescriptionText;
}
public void CallDescriptionTest2()
{
switch (DescriptionName)
{
case "Test":
DescriptionText = #"{\rtf1\ansi\ Test}";
break;
case "Words":
DescriptionText = #"{\rtf1\ansi\ A really long phrase}";
break;
}
}
In such a case, the RichTextBox (SaveRichTest) will take the data and display it just fine.
However, if I do something like this, where the Description column in the database has the text entered exactly as above (ex - #"{\rtf1\ansi\ Test}"):
private void SaveListTest_SelectedIndexChanged(object sender, EventArgs e)
{
DescriptionName = Convert.ToString(SaveListTest.SelectedItem);
CallDescriptionTest();
//CallDescriptionTest2();
SaveRichTest.Rtf = DescriptionText;
}
public void CallDescriptionTest()
{
using (SqlConnection con = new SqlConnection(BuildDB))
{
con.Open();
string sql = String.Format("Select * from Abilities where Name = '{0}'", DescriptionName);
SqlCommand oCmd = new SqlCommand(sql, con);
using (SqlDataReader oReader = oCmd.ExecuteReader())
{
while (oReader.Read())
{
DescriptionText = Convert.ToString(oReader["Description"]);
}
con.Close();
}
}
}
This will instead cause the program to crash, with an error that the "File format is not valid".
I know the text is pulling from the database correctly, because if I change "SaveRichTest.Rtf" to "SaveRichTest.Text", it displays it properly (albeit with the RTF formatting code displayed).
I just can't figure out why it won't take the string properly in the second case. It makes no sense to me whatsoever. Can someone help?
I guess in the case when you tried to show your output in plain text your output was: #"{\rtf1\ansi\ Test}
This would mean when you want to show this string formatted directly from the database you would pass it "#"{\rtf1\ansi\ Test}"" instead of the correct format. I'd suggest you store the format without the # in the database and simply show the result.
I am saving a checkbox value using 'Yes' & 'No' and my problem is I have a button click that would allow the user to change the value.
So my logic is, if button is clicked the checkbox value that is no would change to yes.
Here is what I have to save the information originally:
public void StoredProcedure()
{
string privateItem = Private.Checked ? "Y" : "N";
connection.connection1();
if (connection.con.State == ConnectionState.Closed)
connection.con.Open();
using (SqlCommand cmd = new SqlCommand("SaveImage", connection.con))
{
cmd.Parameters.Add("#privatecheck", SqlDbType.Char).Value = privateItem;
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
connection.con.Close();
}
Basically I have a stored procedure in my database that will save my information.
Now what I was thinking to update one value is to basically do the same thing but it resulted in an error for me.
Any help on how to overwrite a previously saved checkbox value would be extremely helpful!
Thanks
I am not entirely clear on what you are asking for so my answer gives two possible solutions:
If you are looking to modify whether or not the control itself is checked or not checked here is a piece of sample code from MSDN:
private void AdjustMyCheckBoxProperties()
{
// Change the ThreeState and CheckAlign properties on every other click.
if (!checkBox1.ThreeState)
{
checkBox1.ThreeState = true;
checkBox1.CheckAlign = ContentAlignment.MiddleRight;
}
else
{
checkBox1.ThreeState = false;
checkBox1.CheckAlign = ContentAlignment.MiddleLeft;
}
// Concatenate the property values together on three lines.
label1.Text = "ThreeState: " + checkBox1.ThreeState.ToString() + "\n" +
"Checked: " + checkBox1.Checked.ToString() + "\n" +
"CheckState: " + checkBox1.CheckState.ToString();
}
If instead you are looking to modify a column in a table, an UPDATE SQL statement will do that for here, MSDN has a nice walkthrough on how to use LINQ and SQL to achieve this which I would recommend reading.
However I see you are using SqlCommand so here is the example code on how to perform an update command (again) from MSDN:
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
All of the above pieces should help you generate a solution.
I have a method where, when the user clicks a button, it selects data from a table and adds it to a text box. The problem is that when a user clicks 2 or more times, the display code runs once for each click and the data is displayed multiple times in the text box.
How can I clear the Text box and display the data only once?
Note: One of the Text boxes by default has a string which I use on a query that gets the data. When I clear the data, the query throws an error since it doesn't have that string I just cleared to finish the query.
This is the code method that I'm using:
private void FillFilds()
{
mycon.Open();
string queryfill= "SELECT *From master where Num=#Num";
oleDbCmd = new OleDbCommand(queryfill, mycon);
oleDbCmd.Parameters.Add("#Lot", OleDbType.VarChar, 40).Value = Numtxt.Text;
OleDbDataReader reader;
try
{
reader = oleDbCmd.ExecuteReader();
reader.Read();
Idlbl.Text += reader[0];
Datetxt.Text += reader[1];
DatePtxt.Value = Convert.ToDateTime(reader[2]);
Jobtxt.Text += reader[3];
NoBtxt.Text += reader[4];
NoPatxt.Text += reader[5];
NoMtxt.Text += reader[6];
Numtxt.Text += reader[7];
NoRtxt.Text += reader[8];
Description.Text += reader[9];
NoMatxt.Text += reader[10];
reader.Close();
}
catch (Exception error)
{
MessageBox.Show(error.ToString());
}
mycon.Close();
}
I think this might clear some questions...
sorry im new at writing in forums.
You could store this default value somewhere, for example as field in the class:
private string DefaultNumber = "12345";
// ...
Then you can assign this value to the TextBox:
Number.Text = DefaultNumber; // instead of Number.Clear() or Number.Text = ""
But you should really use sql-parameters to prevent sql-injection:
string queryfill = "SELECT * From master where Number = #Number";
DataTable table = new DataTable();
using (OleDbConnection conn = new OleDbConnection(ConnString))
using (OleDbDataAdapter da = new OleDbDataAdapter(queryfill, conn))
{
da.SelectCommand.Parameters.AddWithValue("Number", Number.Text);
da.Fill(table);
}
If the text is showing up multiple times in the text box, then you must be appending it rather than setting it. Make sure that you set the .Text value of the textbox using the = sign rather than appending to whatever is there (such as with +=).
You may also want to consider hard coding your default rather than relying on it being displayed in a text box. You can check if the text box is empty or not. If it is empty, then you can use the default, if it is not empty, you can use the entered value. Use String.IsNullOrEmpty(textbox.Text) to check if the string is empty.
You should also note that your code is completely insecure and would allow someone to do anything they wanted with your database through an attack called SQL Injection. You should never allow user input to be passed directly in to a SQL statement. Instead, you should use parameterized SQL and pass the user input as a parameter. This prevents a hacker from being able to insert additional SQL commands in to the input. For example, in this case, if I put '); DROP TABLE Master; SELECT * FROM passwords(' in your textbox, it would destroy your master table.
I've created a ListView in a new WPF window and also a function that populates the ListView when it is called. This function just takes the URL of my web server where I've stored the data, increments the "id" and gets the data and stores it in the ListView. Therefore it populates the ListView with a certain number of items.
The problem I'm facing is that I want to add two buttons, ON & OFF, to each ListView item as it gets populated programmatically. i.e, if 16 items are added, I want 2 buttons for each item, and if it's 12 items, the similar procedure. Here's my code:
namespace user_login
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Window1 W = new Window1();
public MainWindow()
{
InitializeComponent();
}
public void populate()
{
int i;
int num = 16;
for (i = 1; i <= num; i++)
{
string val = Convert.ToString(i);
string currentUrl = "http://xpleria.com/devices.php?query=dev&id=";
string newUrlWithChangedSort = ReplaceQueryStringParam(currentUrl, "id", val);
string result = getcontent(newUrlWithChangedSort);
W.list1.Items.Add(result);
}
}
public string getcontent(string URL)
{
string content = "";
// Get HTML data
WebClient client = new WebClient();
try
{
content = client.DownloadString(URL);
}
catch (Exception)
{
System.Windows.Forms.MessageBox.Show("No Connection detected!!!");
}
return content;
}
public static string ReplaceQueryStringParam(string currentPageUrl, string paramToReplace, string newValue)
{
string urlWithoutQuery = currentPageUrl.IndexOf('?') >= 0
? currentPageUrl.Substring(0, currentPageUrl.IndexOf('?'))
: currentPageUrl;
string queryString = currentPageUrl.IndexOf('?') >= 0
? currentPageUrl.Substring(currentPageUrl.IndexOf('?'))
: null;
var queryParamList = queryString != null
? HttpUtility.ParseQueryString(queryString)
: HttpUtility.ParseQueryString(string.Empty);
if (queryParamList[paramToReplace] != null)
{
queryParamList[paramToReplace] = newValue;
}
else
{
queryParamList.Add(paramToReplace, newValue);
}
return String.Format("{0}?{1}", urlWithoutQuery, queryParamList);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
string user = textbox1.Text;
string password = textbox2.Password;
string currentUrl = "http://xpleria.com/login.php?query=login&user=wcam&pass=wireless";
string newUrlWithChangedSort = ReplaceQueryStringParam(currentUrl, "user", user);
string newUrl = newUrlWithChangedSort;
string FinalUrl = ReplaceQueryStringParam(newUrl, "pass", password);
string result= getcontent(FinalUrl);
string value = result.Substring(0, 8);
string invalid = "xpleria0";
string valid = "xpleria1";
if (value.Equals(invalid))
{
System.Windows.MessageBox.Show("The Username and/or Password you have entered is invalid, please try again");
}
else if (value.Equals(valid))
{
string sessionID = result.Substring(8, 32);
System.Windows.MessageBox.Show("HI, WELCOME CLETA");
this.Close();
using (new user_login.loading.PleaseWait(this.Location))
{
W.Show();
populate();
}
}
}
public System.Drawing.Point Location { get; set; }
}
}
I'm going to recommend you take a step back and start giving some serious consideration to organizing your code. I realize this isn't an answer to the question you asked but it is the answer to the question you should be asking.
First of all, all code relating to the retrieval of these items from the URL should be moved into a class of some kind. This class should accept the URL string as a constructor parameter and gather all the appropriate data. You should then create another class which you will use to populate with the data for each individual item and then expose this list. By the time you're done the code in your window should little more complex than:
var ItemsGetter = new ItemsGetter(URL);
foreach(var Item in ItemsGetter.Items)
{
// Populate the ListView
}
Once you're done with that I recommend you create a UserControl. User controls are extremely useful in situations where you need to represent a dynamic number of data entities each with their own set of controls which allow operations to be performed on each one. You should create a UserControl with a label and the two buttons you need. The UserControl's constructor should expect a parameter of the data type you created to represent each one of your classes. From there you can have the buttons operate on the data type as necessary.
Finally, you'll probably need a way to have the UserControl interact with the Window. Say for example one of your buttons is "Delete". You'd probably want the item to disappear from the list once the operation is complete. Don't be tempted to tie in your control with the Window by passing it as a parameter or something. Instead, read up on Action events and learn how you can create an event on the user control which you bind in the foreach loop of the Window when you're populating the list view. When the UserControl has completed the delete operation triggered by the button you can raise the UserControl's event which will prompt the Window to remove the control from the List View.
Last but not least, NAME YOUR CONTROLS.
Hopefully this helps.